ES6快速入门第五章------正则的扩展(可私信解惑)
-
正则(RegExp)构造函数
本节须知:学习本节需掌握正则表达式的相关知识。
在ES5中,RegExp构造函数的参数有两种情况。
- 第一种情况是,参数是字符串,这时第二个参数表示正则表达式的修饰符(flag)。
var regex = new RegExp('xyz', 'i');
// 等价于
var regex = /xyz/i;
- 第二种情况是,参数是一个正则表示式,这时会返回一个原有正则表达式的拷贝。
var regex = new RegExp(/xyz/i);
// 等价于
var regex = /xyz/i;
但是,ES5不允许此时使用第二个参数,添加修饰符,否则会报错。
// 报错 Uncaught TypeError: Cannot supply flags when constructing one RegExp from another
var regex = new RegExp(/xyz/, 'i');
-
u修饰符
ES6对正则表达式添加了u修饰符,含义为“Unicode模式”,用来正确处理大于\uFFFF的Unicode字符。也就是说,会正确处理四个字节的UTF-16编码。
/^\uD83D/u.test('\uD83D\uDC2A') // 打印值为false
/^\uD83D/.test('\uD83D\uDC2A') // 打印值为true
上面代码中,\uD83D\uDC2A 是一个四个字节的UTF-16编码,代表一个字符。但是,ES5不支持四个字节的UTF-16编码,会将其识别为两个字符,导致第二行代码结果为true。加了u修饰符以后,ES6就会识别其为一个字符,所以第一行代码结果为false。
Unicode字符表示法
ES6新增了使用大括号表示Unicode字符,这种表示法在正则表达式中必须加上u修饰符,才能识别。
/\u{61}/.test('a') // 打印结果 false
/\u{61}/u.test('a') // 打印结果true
以上代码表示,如果不加u修饰符,正则表达式无法识别\u{61}这种表示法,只会认为这匹配61个连续的u。
ES6改变了这种行为。如果RegExp构造函数第一个参数是一个正则对象,那么可以使用第二个参数指定修饰符。
而且,返回的正则表达式会忽略原有的正则表达式的修饰符,只使用新指定的修饰符。
new RegExp(/xyz/ig, 'i').flags // 返回值 i flags属性,会返回正则表达式的修饰符。
上面代码中,原有正则对象的修饰符是ig,它会被第二个参数 i 覆盖。
-
y 修饰符
除了u修饰符,ES6还为正则表达式添加了y修饰符,叫做“粘连”(sticky)修饰符。
y修饰符的作用与g修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始(也就是剩余字符的头部开始匹配)。而g修饰符只要剩余位置中存在匹配即可。
var s = 'aaa_aa_a'; // 字符串
// 正则声明,此处是字面量方式,还有一种是构造函数方式
var r1 = /a+/g; // 带g修饰符
var r2 = /a+/y; // 带y修饰符
//第一次匹配
r1.exec(s) // 匹配结果 ["aaa"] , 剩余字符串_aa_a
r2.exec(s) // ["aaa"] 剩余字符串_aa_a
//第二次匹配
r1.exec(s) // ["aa"]
r2.exec(s) // null 剩余字符串_aa_a头部 是 _ 不符合,所以返回null
上面代码有两个正则表达式,一个使用g修饰符,另一个使用y修饰符。这两个正则表达式各执行了两次,第一次执行的时候,两者行为相同,剩余字符串都是 _aa_a。由于g修饰没有位置要求,所以第二次执行会返回结果,而y修饰符要求匹配必须从头部开始,所以返回null。
sticky属性
使用sticky可以查看正则声明是否设置了y修饰符。
var r = /abc\d/y;
r.sticky // true
flags属性
ES6为正则表达式新增了flags属性,会返回正则表达式的修饰符。
// ES5的source属性,返回正则表达式的正文
/abc/ig.source // "abc"
// ES6的flags属性,返回正则表达式的修饰符
/abc/ig.flags // 'gi'