原文链接:http://javascript.info/regexp-backreferences,translate with ❤️ by zhangbao.

分组捕获不是仅支持在结果里访问到,在替换字符串和模式里也能访问。

替换字符串里的分组:$n

在我们使用 replace 方法的时候,可以在替换字符串里使用 $n 访问到第 n 个分组内容。

例如:

  1. let name = 'John Smith';
  2. name = name.repalce(/(\w+) (\w+)/i, '$2, $1');
  3. alert( name ); // Smith, John

替换字符串里的 $1 表示”第一分组匹配的内容”,$2 表示”第二个分组匹配的内容”。在替换字符串中引用一个组可以让我们在替换过程中重用现有的文本。

模式里的分组:\n

分组还可以在模式里使用 \n(这里的 n 表示一个数字) 引用。

为了更好的说明,我们需要找一个字符串作说明:我们要匹配的是既有单引号 '...' 又有双引号 "..." 的一段文本,要匹配这两个引号。

那怎么去找呢?

我们可以把两种类型的引号放在一个模式里:['"](.*?)['"]

这个模式会查找像 "..."'...' 里的内容,但是当一个引用出现在另一个引号中时,它会给出不正确的匹配结果,像 "She's the one!"

  1. let str = '他说:"She\'s the one".';
  2. let reg = /['"](.*?)['"]/g;
  3. // 结果并非是我们想要的
  4. alert( str.match(reg) ); // "She'

我们看到,模式找到了开启引号 ",然后文本被惰性地消耗,直到另一个引号 ',然后匹配就关闭了。

为了确保这个模式结尾引号和开头匹配到的引号是一样的,让我们第一个匹配项包进一个组,然后使用回溯引用调用它:

  1. let str = '他说:"She\'s the one".';
  2. let reg = /(['"])(.*?)\1/g;
  3. alert( str.match(reg) ); // "She's the one!"

现在 OK 了!正则表达式找到第一个引号 (['"]) 并且记住了 (...) 里的内容,也就是第一个分组里捕获的内容。

也就是说模式 \1 表示”查找和第一个分组里相同的文本”。

请注意:

  • 在替换字符串引用分组,使用 $1;而在模式里,使用反斜线 \1

  • 如果我们在分组前使用 ?:,我们就不能引用了。(?:...) 的分组是排除在引擎的记忆分组之列的。

(完)