ES9中正则表达式相干次要有两个提案:正则表达式命名捕捉组 & 正则表达式dotAll模式,目前都已进入stage4阶段。
正则表达式命名捕捉组
ECMAScript提案“正则表达式命名捕捉组”proposal-regexp-named-group 由 Gorkem Yakin, Daniel Ehrenberg负责。
1. 什么是捕捉组
捕捉组就是把正则表达式中子表达式匹配的内容,保留到内存中以数字编号或显示命名的组里,不便前面援用,且这种援用既能够在正则表达式外部,也能够在正则表达式内部。
捕捉组有两种模式,一种是一般捕捉组,另一种是命名捕捉组。
目前JavaScript只反对数字模式的一般捕捉组,而这个提案就是为了给JavaScript减少命名捕捉组。
2.捕捉组编号规定
编号规定指的是以数字为捕捉组进行编号的规定, 编号0的捕捉组代表正则表达式整体。
const regex = /(\d{4})-(\d{2})-(\d{2})/;const matchers = regex.exec('2020-12-02');console.table(matchers)
3.命名捕捉组
应用数字捕捉组的一个毛病是对于援用不太直观。比方下面的例子,咱们绝对比拟难分分明哪个组代表年,哪个组代表月或者日。而且,当咱们交互了年和月的值时,应用捕捉组援用的代码都须要更改。
而命名捕捉组就是为了解决这个问题。
命名捕捉组能够应用(?<name>...)语法给每个组起个名称。因而,用来匹配日期的正则表达式能够写为:
/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
每个捕捉组的名字必须惟一,否则会抛出异样:
另外,捕捉组的名字必须合乎JavaScript命名标准:
命名捕捉组能够通过匹配后果的groups
属性拜访。
let regx = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;let result = regx.exec('2020-12-02');result.groups.year === '2020';result.groups.month === '12';result.groups.day === '02';result[0] === '2020-12-02';result[1] === '2020';result[2] === '12';result[3] === '02';
应用解构赋值的例子:
let regx = /^(?<one>.*):(?<two>.*)$/;let {groups: {one, two}} = regx.exec('foo:bar');console.log(`one: ${one}, two: ${two}`);
4.反向援用
当须要在正则表达式外面援用命名捕捉组时,应用\k<name>
语法。
let duplicate = /^(?<half>.*).\k<half>$/;duplicate.test('a*b'); // falseduplicate.test('a*a'); // true
如果援用一个不存在的命名捕捉组,会抛出异样:
命名捕捉组也能够和一般数字捕捉组一起应用:
let triplicate = /^(?<part>.*).\k<part>.\1$/;triplicate.test('a*a*a'); // truetriplicate.test('a*a*b'); // false
5.替换
命名捕捉组也能够在String.prototype.replace
函数中援用,应用$<name>
语法。
let regx = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;let result = "2020-12-02".replace(regx, '$<day>/$<month>/$<year>');console.log(result === '02/12/2020');
String.prototype.replace
第2个参数能够承受一个函数。这时,命名捕捉组的援用会作为 groups
参数传递进取。
第2个参数的函数签名是function (matched, capture1, ..., captureN, position, S, groups)
。
let regx = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;let result = '2020-12-02'.replace(regx, (...args)=>{ let { day, month, year } = args[args.length - 1]; return `${day}/${month}/${year}`});result === '02/12/2020';
6.命名捕捉组未匹配
如果一个可选的命名捕捉组没有匹配时,在匹配后果中,此命名组仍然存在,值是undefined
。
let regx = /^(?<optional>\d+)?$/;let matchers = regx.exec('');matcher[0] === '';matchers.groups.optional === undefined;
如果捕捉组不是可选的,匹配后果是null
。
let regx = /^(?<foo>\d+)$/;let matchers = regx.exec('');matchers === null;
7. 向下兼容
/(?<name>)/
和/\k<name>/
只有在命名捕捉组中才有意义。如果正则表达式没有命名捕捉组,那么/\k<name>/
仅仅是字符串字面量"k<name>"
而已。
8. 实现
- V8, shipping in Chrome 64
- XS, in January 17, 2018 update
- Transpiler (Babel plugin)
- Safari beginning in Safari Technology Preview 40
正则表达式dotAll模式
- 转自 https://esnext.justjavac.com/... 有改变