ES6 正则的扩展
一,RegExp 构造函数
es5中,RegExp构造函数的参数有两种情况。
1,参数是字符串,第二个参数表示正则表达式的修饰符(flag)。
2,参数是一个正则表达式,返回一个原有正则表达式的拷贝。
es6中,如果RegExp构造函数第一个参数是一个正则对象,那么可以使用第二个参数指定修饰符。而且,返回的正则表达式会忽略原有的正则表达式的修饰符,只使用新指定的修饰符。
new RegExp(/abc/ig,'i').flags // 返回 i,原有的ig被替换为i
二,字符串的正则方法
es5:match(),replace(),search(),split()
es6:将es5的4个方法,在语言内部全部调用regexp的实例方法,而从做到所有与正则相关的方法,全部定义在RegExp对象上。
-String.prototype.match 调用 RegExp.prototype[Symbol.match] 类似的replace,search,split方法同理
三,U修饰符
es6对正则表达式添加了U修饰符,含义为“Unicode"模式,用来正确处理大于\uFFFF得Unicode字符。也就是说,会正确处理四个字节得=的UTF-16编码。
一旦加上U修饰符号,就会修改下面这些正则表达式的行为。
(1)点字符
点(.)字符在正则表达式中,含义是除了换行符以外的任意单个字符。对于码点大于oxFFFF的Unicode字符,点字符不能识别,必须加上U修饰符。
var s = '𠮷'; /^.$/.test(s) // false /^.$/u.test(s) // true
(2) Unicode字符表示法
es6新增了使用大括号表示Unicode字符,这种表示法在正则表达式中必须加上u修饰符,才能识别当中的大括号,否则会被解读为量词。
/\u{61}/.test('a') // false /\u{61}/u.test('a') // true /\u{20BB7}/u.test('𠮷') // true
代码表示,如果不加u修饰符,正则表达式无法识别\u{61}这种表示法,只会认为这匹配61个连续的u.
(3) 量词
/a{2}/.test('aa') // true /a{2}/u.test('aa') // true /𠮷{2}/.test('𠮷𠮷') // false /𠮷{2}/u.test('𠮷𠮷') // true
(4)预定义模式
/^\S$/.test('𠮷') // false /^\S$/u.test('𠮷') // true
\s是预定义模式,匹配所有非空白字符。
(5)i 修饰符
有些Unicode字符的编码不同,但是字形相近,比如\u0048与\u2121都是大写的k
/[a-z]/i.test('\u212A') // false /[a-z]/iu.test('\u212A') // true 上面代码中,不加u修饰符,就无法识别非规范的K字符。
四,RegExp.prototype.unicode属性
正则实例对象新增Unicode属性,表示是否设置了u 修饰符。
const r1 = /hello/; const r2 = /hello/u; r1.unicode // false r2.unicode // true
五,y修饰符
除了u修饰符,es6还为正则表达式添加了Y修饰符,叫做"粘连"修饰符。y修饰符的作用与g修饰符类似,也是全局匹配,区别:g修饰符只要剩余位置中存在匹配就可,而y修饰符确保匹配需从剩余的第一个位置开始,这也就是”粘连“的含义。
var s = 'aaa_aa_a'; var r1 = /a+/g; var r2 = /a+/y; r1.exec(s) // ["aaa"] r2.exec(s) // ["aaa"] r1.exec(s) // ["aa"] r2.exec(s) // null
六,RegExp.prototype.sticky 属性
表示是否设置了y修饰符
七,RegExp.prototype.flags属性
返回正则表达式的修饰符
八,s修饰符:dotAll模式
const re = /foo.bar/s; // 另一种写法 // const re = new RegExp('foo.bar', 's'); re.test('foo\nbar') // true . = \n re.dotAll // true re.flags // 's'
十,Unicode属性类
es2018引入了一种新的类的写法 \p{...}和\P{...},允许正则表达式匹配符合uNicod某种属性的所有字符。
十一,具名组匹配
正则表达式使用圆括号进行匹配。
es2018引入了具名组匹配(Named Capture Groups) ,允许为每一个组匹配指定一个名字,既方便阅读代码,又便于引用。
const RE_Date = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/; const matchObj = RE_DATE.exec('1991-12-31'); const year = matchObj.groups.year; const month = matchObj.groups.month; const day = matchObj.groups.day;
模式匹配头部添加"问号+尖括号+组名“(?<year>),通过exec方法返回的结果的属性groups上引用属性。
解构赋值和替换
let re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u; '2015-01-02'.replace(re,'$<day>/$<month>/$<year>'); // '02/01/2015'
引用
如果要在正则表达式内部引用某个”具名组匹配“ 可以使用\k<组名>的写法
十二,String.prototype.matchAll
如果一个正则表达式在字符串中有多个匹配,现在一般使用g修饰符和y修饰符,在循环里面逐一取出。
目前,增加了String.prototype.matchAll方法,可以一次性取出所有匹配。不过,它返回的是一个遍历器,而不是数组。 返回的遍历器,可以通过for...of循环取出。
遍历器转为数组,使用...运算符和Array.form方法就可以