ECMAScript 6 笔记(5)- 正则的扩展

原创 乘风逐月 随笔 ES6 183阅读 2018-08-23 15:19:21 举报

阅读原文: 阮一峰:ECMAScript 6 入门

一、RegExp 构造函数

在ES5中,RegExp 构造函数的参数有两种情况。
一是: 参数是字符串,这时第二个参数表示正则表达式的修饰符:

二是: 参数是一个正则表达式,这时会返回一个原有的正则表达式的拷贝。此种情况,不允许使用第二个参数添加修饰符,否则会报错:

ES6 则允许第一个参数是一个正则对象时,可以使用第二个参数来指定修饰符。
注: 返回的正则表达式会会忽略原有的正则表达式的修饰符,只使用新指定的修饰符。

二、字符串的正则方法

字符串对象共有4个方法,可以使用正则表达式:match(),replace(),search(),split()。
ES6将这四个方法,在语言内部全部调用 RegExp 的实例方法,从而做到所有与正则相关的方法,全部定义在 RegExp 对象上。
a. String.prototype.match 调用 RegExp.prototype[Symbol.match]
b. String.prototype.replace 调用 RegExp.prototype[Symbol.replace]
c. String.prototype.search 调用 RegExp.prototype[Symbol.search]
d. String.prototype.split 调用 RegExp.prototype[Symol.split]

三、u 修饰符

ES6 对正则表达式添加了u 修饰符,含义为 "Unicode" 模式,用来处理大于 \uFFFF 的 Unicode 字符。也就是说,会正确处理四个字节的 UTF-16 编码。

上面代码中,\uD83D\uDC2A 是一个四字节的 UTF-16 编码,代表一个字符。但是,ES5不支持四个字节的 UTF-16 编码,会将其识别为两个字符,导致第二行代码结果为 true。 加了 u 修饰符后,就会修改下面这些正则表达式的行为:

(1)点字符

点(.)字符在正则表达式中,含义是任何除了换行符以外的任意单个字符。对于码点大于 0xFFFF 的 Unicode 字符,点字符不能识别,必须加上 u 修饰符。

上面代码,如果不添加 u 修饰符,正则表达式就会认为字符串是两个字符,从而匹配失败。

(2)Unicode 字符表示法

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

上面代码,如果不加 u 修饰符,正则表达式无法识别 \u{61} ,只会被认为匹配61个连续的 u。

(3)量词

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

(4)预定义模式

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

/S 是预定义模式,匹配所有非空白字符。只有加了 u 修饰符,它才能正确匹配码点大于 0xFFFF 的 Unicode 字符。

(5)i 修饰符

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

四、RegExp.prototype.unicode 属性

正则实例对象新增 unicode 属性,表示是否设置了 u 修饰符。

五、y修饰符

除了 u 修饰符,ES6还为正则表达式添加了 y 修饰符,叫做 "粘连" 修饰符。
y 修饰符的作用与 g 修饰符类似,也是全局配置,后一次匹配都从上一次匹配成功的下一个位置开始。不同之处在于,g 修饰符只要剩余位置中存在匹配就可,而 y 修饰符确保匹配必须从剩余的第一个位置开始。

上例中,两个正则表达式使用了不同的修饰符。第一次执行的时候,两者行为相同,剩余的字符串都是 '_aa_a'。 由于 g 修饰符没有位置要求,所以第二次执行会返回结果。而 y 修饰符要求匹配必须从头开始,所以返回 null 。

使用 lastIndex 能更好的说明 y 修饰符,但是要求必须在 lastIndex 指定的位置发现匹配:

实际上,y 修饰符号隐含了头部匹配的标志 ^。y 修饰符的设计本意,就是让头部匹配的标志 ^ 在全局中有效。

六、RegExp.prototype.sticky 属性

与 y 修饰符相匹配,ES6 的正则实例对象多了 sticky 属性,表示是否设置了 y 修饰符。

七、RegExp.prototype.flags 属性

ES6 为正则表达式新增了 flags 属性,会返回正则表达式的修饰符。

八、 s 修饰符:dotAll 模式

正则表达式中,点(.)是一个特殊字符,代表任意单个字符。但是有两个例外:一是:四个字节的 UTF-16字符,这个可以用 u 修饰符解决;另一个是行终止符。
所谓行终止符,就是该字符表示一行的终结。以下四个字符表示 "行终止字符":
a. U+000A 换行符(\n)
b. U+000D 回车符(\r)
c. U+2028 行分隔符
d. U+2029 段分隔符
s 修饰符,使得 (.)可以匹配任意单个字符。

这被称为 dotAll 模式,即点代表一切字符,所以正则表达式还引入了一个 dotAll 属性,返回一个布尔值,表示该正则是否处在 dotAll 模式。

九、具名组匹配

(1)使用方法

正则表达式使用圆括号进行组匹配。

上例中,可以将每一个组匹配的结果提取出来。但是,每一组的匹配含义不容易看出来,而且只能用数字序号引用,要是组的顺序变了,引用的时候就必须修改序号。

ES6 引入了 "具名组匹配" ,允许为每一个组匹配指定一个名字,便于阅读引用。

上例中, "具名组匹配" 在原括号内部,模式的头部添加 "问号+尖括号+组名",然后就可以在 exec() 方法返回的结果 groups 属性上引用该组名。同时,数字序号依然有效。
具名组匹配等于为每一组匹配加上了 ID,便于描述匹配的目的。如果组的顺序变了,也不改变匹配后的处理代码。
如果没有具名组匹配,那么对应的 groups 对象属性会是 undefined 。

(2)匹配结果解构赋值

有了具名组匹配,可以使用解构赋值直接从匹配结果上为变量赋值。

(3)字符串替换引用具名组

字符串替换时,使用 $<组名> 引用具名组。

上面的代码中,replace 方法的第二个参数是一个字符串,而不是正则表达式。

(4)正则表达式内引用具名匹配组

如果要在正则表达式内部引用某个 "具名组匹配" ,可以使用 \k<组名> 的写法。也可以使用数字引用 \1 依然有效。

评论 ( 11 )
最新评论
lawrence 10F 2018-08-31 16:34:11 11F

多久估一次啊

乘风逐月 9F 2018-08-31 16:30:30 10F

以前是项目经理定项目时间,现在是我们拿到需求后开发人员自己评估时间,那可以根据项目难度,自己定出大概时间。如果自己定的时间做不完,那肯定要加班了。

lawrence 8F 2018-08-31 15:25:45 9F

老板不会给你做不完的事情么:)

乘风逐月 7F 2018-08-31 14:54:40 8F

合理规划项目,尽量上班时间完成任务,除非紧急情况,拒绝无意义拖时间的加班。

lawrence 6F 2018-08-30 20:33:32 7F

你们公司这么闲啊?

乘风逐月 5F 2018-08-29 16:29:11 6F

六点下班

lawrence 4F 2018-08-28 15:31:24 5F

晚上几点下班啊

乘风逐月 3F 2018-08-28 15:11:13 4F

加班不是很多

lawrence 2F 2018-08-27 16:05:08 3F

你在做什么项目啊?平时加班多么?

乘风逐月 1F 2018-08-27 08:56:29 2F

我是没项目了,去看两眼,所以慢。

lawrence 2018-08-26 08:15:01 1F

楼主,你是不是学的太慢了?