前言

本章介绍正则的扩展。有些不常用的知识了解即可。

本章原文链接:正则的扩展

RegExp 构造函数

从 ES6 开始,如果RegExp构造函数第一个参数是一个正则对象,并且第二个标志存在且为标志参数,将不再抛出 TypeError ,将使用这些参数创建一个新的正则表达式。原有的正则表达式修饰符将被忽略

const flag = new RegExp(/[0-9]/ig, 'i').flags; // 原有修饰符卫 ig ,被 i 给替代了
console.log(flag); // i

字符串有关正则表达式

ES6将之前字符串上的四个关于正则表达式的方法全部更改为RegExp的实例方法,所以现在所有与正则表达式有关的方法,全部定义在RegExp对象上。

  • String.prototype.match 调用 RegExp.prototype[Symbol.match]
  • String.prototype.replace 调用 RegExp.prototype[Symbol.replace]
  • String.prototype.search调用 RegExp.prototype[Symbol.search]
  • String.prototype.split调用 RegExp.prototype[Symbol.split]

flags 属性

RegExp.prototype.flags 属性 是ES6新增属性,会返回正则表达式的修饰符。

const SAMPLEREG = /abc/ig;
console.log(SAMPLEREG.flags); // gi

u 修饰符

在ES6中新增了 u修饰符,表示使用Unicode码的模式进行匹配。处理大于\uFFFF的 Unicode 字符

注意

一旦加上u修饰符号,就会修改下面这些正则表达式的行为。

  1. 点字符

对于码点大于0xFFFF的 Unicode 字符,点字符不能识别,必须加上u修饰符。

  1. **Unicode**** 字符表示法**

新增了使用大括号表示 Unicode 字符,这种表示法在正则表达式中必须加上u修饰符,才能识别当中的大括号,否则会被解读为量词。

  1. 量词

使用u修饰符后,所有量词都会正确识别码点大于0xFFFF的 Unicode 字符。

  1. 预定义模式

u修饰符也影响到预定义模式,能否正确识别码点大于0xFFFF的 Unicode 字符。

  1. i 修饰符

有些 Unicode 字符的编码不同,但是字型很相近,比如,\u004B与\u212A都是大写的K

  1. 转义

没有u修饰符的情况下,正则中没有定义的转义(如逗号的转义\,)无效,而在u模式会报错。

unicode 属性

RegExp.prototype.unicode 属性表明正则表达式带有"u" 标志。 unicode 是正则表达式独立实例的只读属性。

​

const SAMPLEREG = /abc/u;

console.log(SAMPLEREG.flags); // u
console.log(SAMPLEREG.unicode); // true

Unicode 属性类

**Unicode property escapes**

ES2018 引入了一种新的类的写法\p{...}和`P{...},用于解决 JavaScript 没有强有效的方式用匹配出不同文字问题。允许正则表达式匹配符合 Unicode` 某种属性的所有字符。

\p{Unicode属性名=Unicode属性值}
// 对于某些属性,可以只写属性名,或者只写属性值。
\p{Unicode属性值}
\p{Unicode属性名} // \P 为 \p 取反
\P{Unicode属性值}
\P{Unicode属性名}

注意:

这两种类只对 Unicode 有效,所以使用的时候一定要加上u修饰符。

\P{…}是\p{…}的反向匹配,即匹配不满足条件的字符。

const SAMPLEREG = /\p{Script=Greek}/u;
SAMPLEREG.test('π'); // true

y 修饰符

y 修饰符的作用

在ES6中新增了 y 修饰符,表示执行“粘性(sticky)”搜索,匹配从目标字符串的当前位置开始。

y修饰符与g修饰符相似,都是全局匹配,后一次匹配从上一次匹配成功的下一个位置开始。

区别是:g修饰符只要剩余位置中存在匹配即可;而y修饰符必须从剩余的第一个位置开始匹配。

// y修饰符与g修饰符的区别
const SAMPLE = 'abcdabcd';
const SAMPLEREG1 = /abcd/g;
const SAMPLEREG2 = /abcda/y; console.log(SAMPLEREG1.test(SAMPLE)); // true
console.log(SAMPLEREG2.test(SAMPLE)); // true
console.log(SAMPLEREG1.test(SAMPLE)); // true
console.log(SAMPLEREG2.test(SAMPLE)); // false

​

注意

实际上,y修饰符号隐含了头部匹配的标志^。

const SAMPLEREGGY = /ab/gy;
const SAMPLEREGY = /ab/y; let sample1 = 'ababcabcd'.replace(SAMPLEREGGY, '-');
let sample2 = 'ababcabcd'.replace(SAMPLEREGY, '-'); // 最后一个ab因为不是出现在下一次匹配的头部,所以不会被替换。
console.log(sample1);
// 只能返回第一个匹配,必须与g修饰符联用,才能返回所有匹配。
console.log(sample2);

sticky 属性

RegExp.prototype.sticky表示是否设置了y修饰符。sticky 是正则表达式对象的只读属性。

const SAMPLEREG = /a/gy;
console.log(SAMPLEREG.sticky); // true

s 修饰符

ES2018 引入s修饰符,使得.可以匹配任意单个字符。包括行终止符(line terminator character)。

行终止符

所谓行终止符,就是该字符表示一行的终结。以下四个字符属于“行终止符”。

  • U+000A 换行符(\n)
  • U+000D 回车符(\r)
  • U+2028 行分隔符(line separator)
  • U+2029 段分隔符(paragraph separator)
const SAMPLEREG = /ab.cd/s;
console.log(SAMPLEREG.test('ab\ncd') ); // true

dotAll

上面这种情况被称为**dotAll**模式,即点(dot)代表一切字符。正则表达式还引入了一个**dotAll**属性

dotAll 属性返回一个布尔值,表明是否在正则表达式中一起使用"s"修饰符。dotAll 是一个只读的属性,属于单个正则表达式实例。

    const SAMPLEREG = /ab.cd/s;
const sample = SAMPLEREG.test('ab\ncd');
console.log(SAMPLEREG.flags); // s
console.log(SAMPLEREG.dotAll); // true

后行断言

ES2018 引入后行断言,V8 引擎 4.9 版(Chrome 62)已经支持。

  • 先行断言

    x只有在y前面才匹配,必须写成/x(?=y)/。

    比如,只匹配百分号之前的数字,要写成/\d+(?=%)/。

  • 先行否定断言,

    x只有不在y前面才匹配,必须写成/x(?!y)/。

    比如,只匹配不在百分号之前的数字,要写成/\d+(?!%)/。

  • 后行断言正好与先行断言相反,

    x只有在y后面才匹配,必须写成/(?<=y)x/。

    比如,只匹配美元符号之后的数字,要写成/(?<=\$)\d+/。

  • 后行否定断言则与先行否定断言相反,

    x只有不在y后面才匹配,必须写成/(?<!y)x/。

    比如,只匹配不在美元符号后面的数字,要写成/(?<!\$)\d+/。

后行断言需要先匹配/(?<=y)x/的x,然后再回到左边,匹配y的部分。顺序为先右后左,

// 先行断言
const sample1 = /\d+(?=%)/.exec('100% of US presidents have been male');
// 先行否定断言
const sample2 = /\d+(?!%)/.exec('that’s all 44 of them');
console.log(sample1); // 100
console.log(sample2); // 44 // 后行断言
const sample3 = /(?<=\$)\d+/.exec('Benjamin Franklin is on the $100 bill');
// 后行否定断言
const sample4 = /(?<!\$)\d+/.exec('it’s is worth about €90');
console.log(sample3); // 100
console.log(sample4); // 90

组匹配

正则表达式的括号表示分组匹配,括号中的模式可以用来匹配分组的内容。

ES2018 引入了具名组匹配(Named Capture Groups),允许为每一个组匹配指定一个名字,既便于阅读代码,又便于引用。

具名组匹配在圆括号内部,模式的头部添加“问号 + 尖括号 + 组名”(?<year>),然后就可以在exec方法返回结果的groups属性上引用该组名。同时,数字序号依然有效。

const sampleUsers = `
姓刘名备字玄德
姓关名羽字云长
姓张名飞字翼德`;
const SAMPLEREG = /姓(?<surnames>.+)名(?<name>.+)字(?<word>.+)/g;
let result = SAMPLEREG.exec(sampleUsers); do { console.log(`${result.groups.surnames}${result.groups.name}${result.groups.surnames}${result.groups.word}`);
} while ((result = SAMPLEREG.exec(sampleUsers)) !== null); /*
* 刘备刘玄德
* 关羽关云长
* 张飞张翼德
*/

上面的代码中:?<xxx>的作用就是为这个匹配定义一个组名,在匹配的groups属性中可以查看到匹配的组名,这里可以使用解构赋值直接从匹配结果上为变量赋值。

注意 : 如果要在正则表达式内部引用某个具名组匹配,可以使用\k<组名>的写法

matchAll()

ES2020 增加了String.prototype.matchAll()方法,可以一次性取出所有匹配。不过,它返回的是一个遍历器/迭代器(Iterator),而不是数组。

const string = 'sample1sample2sample3';
const regex = /sample/g; for (const match of string.matchAll(regex)) {
console.log(match);
}
// 遍历输出
/*
['sample', index: 0, input: 'sample1sample2sample3', groups: undefined]
['sample', index: 7, input: 'sample1sample2sample3', groups: undefined]
['sample', index: 14, input: 'sample1sample2sample3', groups: undefined]
*/

ES6学习 第五章 正则的扩展的更多相关文章

  1. ES6学习笔记<五> Module的操作——import、export、as

    import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...

  2. Java基础知识二次学习--第五章 数组

    第五章 数组 时间:2017年4月26日15:11:30~2017年4月26日15:15:54 章节:05章_01节  视频长度:09:30 内容:一维数组的内存分析 心得: Java中数组是引用类型 ...

  3. C#高级编程 (第六版) 学习 第五章:数组

    第五章 数组 1,简单数组 声明:int[] myArray; 初始化:myArray = new int[4]; 为数组分配内存. 还可以用如下的方法: int[] myArray = new in ...

  4. C语言学习第五章

    今天要进行一个重要元素数组的学习了.这一章要掌握什么是数组,数组怎么样命名,数组怎么样使用,以及一些常见的错误和需要注意的事项. 一.      数组的基本概念 数组是可以在内存中连续存储多个元素的结 ...

  5. 深度学习框架PyTorch一书的学习-第五章-常用工具模块

    https://github.com/chenyuntc/pytorch-book/blob/v1.0/chapter5-常用工具/chapter5.ipynb 希望大家直接到上面的网址去查看代码,下 ...

  6. ES6学习笔记(七)-对象扩展

    可直接访问有道云笔记分享链接查看es6所有学习笔记 http://note.youdao.com/noteshare?id=b24b739560e864d40ffaab4af790f885

  7. Es6 学习笔记(一)数组扩展

    扩展运算符 ... 1.数组的扩展运算符将一个数组转换成一个逗号分隔的参数序列 console.log(...[1,2,3])   //1,2,3 ['a', 'b',...[1,3]]   //a, ...

  8. Artech的MVC4框架学习——第五章Model的绑定

    第一Model绑定本质就是为目标Action方法生成参数列表的过程,参数数据存在于http请求.请求的 URL .消息报头或主体中. 第二aciton 参数的元数据通过 ParameterDescri ...

  9. ES6学习笔记(四)-数值扩展

    PS: 前段时间转入有道云笔记,体验非常友好,所以笔记一般记录于云笔记中,每隔一段时间,会整理一下, 发在博客上与大家一起分享,交流和学习. 以下:

随机推荐

  1. 洛谷4234最小差值生成树 (LCT维护生成树)

    这也是一道LCT维护生成树的题. 那么我们还是按照套路,先对边进行排序,然后顺次加入. 不过和别的题有所不同的是: 在本题中,我们需要保证LCT中正好有\(n-1\)条边的时候,才能更新\(ans\) ...

  2. cvechecker 漏洞扫描工具部署及效果展示

    cvechecker 漏洞扫描工具部署及效果展示 介绍 cvechecker的目标是通过扫描已安装的软件并将结果与CVE数据库进行匹配来报告系统上可能存在的漏洞. 官方提示: 可能会产生许多误报(漏洞 ...

  3. 【原创】浅谈指针(五)const和指针

    前言 过了几个月再次更新.最近时间也不多了,快要期中考试了,暂且先少写一点吧. 本文仅在博客园发布,如在其他平台发现均为盗取,请自觉支持正版. 练习题 我们先来看几道题目.如果这几道题都不会的话,就先 ...

  4. [no_code][Beta]事后分析

    设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们要解决的目前的手写表单的电子化问题,办公电子化问题的一个key问题.定义十分清楚: 输入: 手写表单 ...

  5. [对对子队]团队任务拆解Alpha

    Alpha阶段主要目标 完成游戏场景的基本实现(不要求美术资源) 完成游戏UI的基本实现(不要求美术资源) 制作第一部分的关卡(顺序语句,制作3-5关) 完成第一部分关卡和游戏基本逻辑的测试 任务分解 ...

  6. pwn200,一道不完全考察ret2libc的小小pwn题

    pwn200 ---XDCTF-2015 每日一pwn,今天又做了一个pwn,那个pwn呢???攻防世界的进阶区里的一道小pwn题,虽然这个题考察的知识不多,rop链也比较好构建,但是还是让我又学到了 ...

  7. Tarjan算法 求 有向图的强连通分量

    百度百科 https://baike.baidu.com/item/tarjan%E7%AE%97%E6%B3%95/10687825?fr=aladdin 参考博文 http://blog.csdn ...

  8. linux下c语言实现简单----线程池

    这两天刚好看完linux&c这本书的进程线程部分,学长建议可以用c语言实现一个简单的线程池,也是对线程知识的一个回顾与应用.线程的优点有好多,它是"轻量级的进程",所需资源 ...

  9. AliRTC 开启视频互动 “零计算” 时代

    在 2021 云栖大会<产业视频化创新与最佳实践>视频云主题论坛中,阿里云智能高级技术专家在<AliRTC 开启视频互动 "零处理" 时代>的主题演讲中,发 ...

  10. 端口被占用(启动tomcat时 错误: 代理抛出异常 : java.rmi.server.ExportException: Port already in use: 1099的解决办法)

    一.问题描述 在IntelliJ IDEA 中启动Tomcat服务器时就出现了如下图所示的错误: 错误: 代理抛出异常错误**: java.rmi.server.ExportException: Po ...