ES6 学习 ---正则的扩展
Posted newttt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6 学习 ---正则的扩展相关的知识,希望对你有一定的参考价值。
正则
正则表达式的声明
1 var regex = new RegExp(‘xyz‘, ‘i‘); // 第一个参数是字符串,第二个参数表示正则表达式的修饰符 2 // 等价于 3 var regex = /xyz/i; 4 5 或 6 7 var regex = new RegExp(/xyz/i); // 参数是一个正则表达式,返回一个正则表达式的拷贝 8 9 // 等价于 10 var regex = /xyz/i;
在ES6中,RegExp构造器函数第一个是正则对象,第二个参数可以是指定修饰符,而这在ES5中是不允许的,会报错;
new RegExp(/abc/ig,"i").flags // i
在这个表达式中,第二个参数修饰符i会覆盖原有正则对象的修饰符ig
字符串的正则方法
字符串对象共有4个方法,可以使用正则表达式: match(), replace(), search() 和 split()
ES6将这4个方法,在语言内部全部调用RegExp的实例方法,从而做到所有与正则相关的方法,全都定义在RegExp对象上
1 // String.prototype.match 调用 RegExp.prototype[Symbol.match] 2 // String.prototype.replace 调用 RegExp.prototype[Symbol.replace] 3 // String.prototype.search 调用 RegExp.prototype[Symbol.search] 4 // String.prototype.split 调用 RegExp.prototype[Symbol.split]
u修饰符
ES6 对正则表达式添加了u修饰符,含义为"Unicode 模式",用来正确处理大于uFFFF的Unicode字符,也就是说,会正确处理四个字节的UTF-16 编码
RegExp.prototype.unicode属性
正则实例对象新增unicode属性,表示是否设置u修饰符
1 const r1 = /hello/;
2 const r2 = /hello/u;
3
4 r1.unicode // false
5 r2.unicode // true
上面代码中,可以用unicode来判断是否设置了u修饰符
y修饰符
除了u修饰符,ES6还为正则表达式添加了y修饰符,叫做"粘连"(sticky)修饰符
y修饰符的作用于g修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始,不同之处在于,g修饰符只要剩余位置中存在匹配就可,而y修饰符确保匹配必须从剩余的第一个位置开始,这也就是"粘连"的含义
1 var s = ‘aaa_aa_a‘;
2 var r1 = /a+/g;
3 var r2 = /a+/y;
4
5 r1.exec(s) // ["aaa"]
6 r2.exec(s) // ["aaa"]
7
8 r1.exec(s) // ["aa"] // 会从_aa_a,中的a开始匹配, g修饰符没有位置要求
9 r2.exec(s) // null // 会从 _aa_a,中的 _ 匹配,因此会返回null, y修饰符必须从头部开始
RegExp.prototype.sticky属性
与y修饰符相匹配,用来判断正则对象是否设置了y修饰符
var r = /hellod/y; r.sticky // true // 判断是否使用y修饰符
RegExp.prototype.flags属性
ES6 为正则表达式新增了flags属性,会返回正则表达式的修饰符
1 // ES5 的 source 属性
2 // 返回正则表达式的正文
3 /abc/ig.source
4 // "abc"
5
6 // ES6 的 flags 属性
7 // 返回正则表达式的修饰符
8 /abc/ig.flags
9 // ‘gi‘
s修饰符: dotAll模式
点(.)元字符,可以代表任意单个字符,但是有两个例外,一个是四字节的UTF-16,这个可以使用u修饰符解决,另一个是行终止符(该字符表示一行的终结 等)
/foo.bar/.test(‘foo
bar‘) // false
/foo.bar/s.test(‘foo
bar‘) // true
ES2018中引入s修饰符,使得.可以匹配任意单个字符,这被称为dotAll模式,即点(dot)代表一切字符,所以正则表达式还引入了一个dotAll属性,返回一个布尔值,表示该正则表达式是否处在dotAll模式
1 const re = /foo.bar/s;
2 // 另一种写法
3 // const re = new RegExp(‘foo.bar‘, ‘s‘);
4
5 re.test(‘foo
bar‘) // true
6 re.dotAll // true
7 re.flags // ‘s‘
具名组匹配
正则表达式使用圆括号进行组匹配
1 const RE_DATE = /(d{4})-(d{2})-(d{2})/; 2 3 const matchObj = RE_DATE.exec(‘1999-12-31‘); 4 const year = matchObj[1]; // 1999 5 const month = matchObj[2]; // 12 6 const day = matchObj[3]; // 31
ES2018 引入了具名组匹配(Named Capture Groups),允许为每一个组匹配指定一个名字,既便于阅读代码,又便于引用。
1 const RE_DATE = /(?<year>d{4})-(?<month>d{2})-(?<day>d{2})/; 2 3 const matchObj = RE_DATE.exec(‘1999-12-31‘); 4 const year = matchObj.groups.year; // 1999 5 const month = matchObj.groups.month; // 12 6 const day = matchObj.groups.day; // 31
如果具名组没有匹配到则该组的值为undefined;
上面 ?<year> 相当于给每个组加了一个变量名,因此,也可以使用解构赋值
即: let { groups: { one, two }} = /^( ?<one>.* ):( ?<two>.*)$/u.exec("foo:bar");
当字符串替换时,使用$<组名>
引用具名组。
1 let re = /(?<year>d{4})-(?<month>d{2})-(?<day>d{2})/u; 2 3 ‘2015-01-02‘.replace(re, ‘$<day>/$<month>/$<year>‘) 4 // ‘02/01/2015‘ 注意: replace的第二参数为字符串
在正则表达式中还可以引用某个具名组匹配
1 const RE = /^(?<word>[a-z]+)!k<word>$/; 2 RE.test(‘abc!abc‘) // true 3 RE.test(‘abc!ab‘) // false 4 5 // 数字引用(1)依然有效。 6 const RE_TWICE = /^(?<word>[a-z]+)!1$/; 7 RE_TWICE.test(‘abc!abc‘) // true 8 RE_TWICE.test(‘abc!ab‘) // false 9 10 // 同是还能两者一起用 11 const RE1= /^(?<word>[a-z]+)!k<word>!1$/; 12 RE1.test(‘abc!abc!abc‘) // true 13 RE1.test(‘abc!abc!ab‘) // false
String.prototype.matchAll
一般来说,正则表达式在字符串.match方法中每次只能匹配到一个,但是 matchAll 一次性可以将所有的匹配项全部取出 返回一个伪数组; 之后可以用 ... 或 Array.from() 在转换成数组
———— 不生产代码,只是代码的搬用工
以上是关于ES6 学习 ---正则的扩展的主要内容,如果未能解决你的问题,请参考以下文章