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/... 有改变