算法与数据结构 / regex · Unicode 字符模型与一个自研引擎 / 命名捕获与反向引用:两种共用 待审核 32 / 36
capture · backref · 两种「共用」

命名捕获与反向引用:两种共用

语法速览 把命名组与反向引用各一笔带过,两者常被混作一谈,实为两种不同的「共用」。命名捕获 (?<x>…) 共用的是语法:给某个捕获组起个名字,这名字只是 \1 这类数字下标的可读别名,指向 pattern 里的那个组,可以在 pattern 内、替换串里与结果对象里到处复用,不增加任何匹配能力。反向引用 \1\k<x> 共用的则是匹配到的文本:它要求之前那个组实际吃到的那串字符原封不动再出现一次。一句话记牢,(\w+) \1 不是「一个词加空格加任意一个词」,而是「一个词加空格加同一个词」。

1 · 名字处处复用

把组起个名,结果里就能按名字取字段,不必数 groups[3] 是第几个;替换时还能按名重排。同时列出编号组与命名组即可看出,namedGroups.y 就是 groups[1],名字纯属别名。开 d 标志还能拿到各命名组的区间。

图 1-1 · 命名捕获的匹配结果与按名替换:并列编号组、命名组与 indices.groups。可改 pattern、flags、输入与替换模板,或点例子。

2 · 共用文本意味着什么

同一段输入,左边用反向引用、右边用两个独立组,结论常常相反:go to 在右边命中、在左边落空,因为两个词不是同一串。开 i 之后 GO go 在左边也能命中——反向引用的判等跟着 i 走大小写折叠,这一点与 大小写 页讲的折叠是同一套规则。

图 2-1 · 同一输入下 (\w+) \1 与 (\w+) (\w+) 的对照,左右各给出命中与理由。可改输入与 flags,或点例子。

3 · 命名反向引用

\k<name> 把两件事合起来用:名字来自命名捕获,判等来自反向引用。配对引号与 HTML 开闭标签是它的典型场景——「同种」「同名」正是「共用同一串文本」。

图 3-1 · \k<name> 的三个场景:配对引号、标签配对与命名叠字。可改 pattern 与输入,或点例子。

注 · 一张表对齐两者:命名捕获复用的是一个名字,作用在读写层面,不改变匹配能力,与编号组等价;反向引用复用的是组实际匹配到的文本,作用在匹配运行时,超出正则语言,引擎因此切到回溯。前者的典型用途是取字段与重排,后者是叠字、重复词与配对。

4 · 参考文献

  1. Ecma International. ECMA-262: Atom 与 AtomEscape. 命名捕获与反向引用的语法定义,以及 \k<name> 的解析规则。tc39.es
  2. MDN. Named capturing group. 命名组在 pattern、替换串与结果对象里的三种用法。developer.mozilla.org
  3. MDN. Backreference. 反向引用的语义与大小写折叠下的判等行为。developer.mozilla.org