5日 六月 2019

反向引用:\n 和 $n

捕获组不仅能在结果中读取,也能在替换字符串,甚至模式中读取。

替换字符串中的组:$n

replace 方法中可以用 $n 在替换字符串中访问第 n 个捕获组。

例如:

let name = "John Smith";

name = name.replace(/(\w+) (\w+)/i, "$2, $1");
alert( name ); // Smith, John

这里替换字符串中的 $1 的意思是“在这里替换第一个捕获组的内容”,$2 的意思是“在这里替换第二个捕获组的内容”。

在替换字符串中引用组允许我们在替换时重用已存在的文本。

模式中的组:\n

在模式中,可以用 \n 引用组。

为了更好的说明,假设有一个任务。我们需要找出带引号的字符串:要么是单引号 '...',要么是双引号 "..." —— 这两种类型都要找出来。

怎么查找这类引用组呢?

模式里要有两种引号:['"](.*?)['"]。匹配形如 "..."'...' 的字符串,但当两类符号存在嵌套是,结果就不正确了,例如字符串 "She's the one!"

let str = "He said: \"She's the one!\".";

let reg = /['"](.*?)['"]/g;

// The result is not what we expect
alert( str.match(reg) ); // "She'

如你所见,这个模式发现了左双引号 ",然后匹配文本直到发现另一个引号 ',结束本次匹配。

为了确保模式匹配的右引号类型和左引号类型一致,可以将引号包裹成组并使用反向引用:

let str = "He said: \"She's the one!\".";

let reg = /(['"])(.*?)\1/g;

alert( str.match(reg) ); // "She's the one!"

现在一切搞定!正则表达式引擎匹配第一个引号 (['"]) 时,记录 pattern(...) 的内容,这就是第一个捕获组。

\1 的含义是“找到与第一组相同的文本”。

请注意:

  • 在替换字符串内部引用组的方式 —— $1,在模式中引用组的方式 —— \1
  • 在组内使用 ?: 则无法引用到该组。正则表达式引擎不会记住被排除在捕获 (?:...) 之外的组。
教程路线图

评论

在评论之前先阅读本内容…
  • 欢迎你在文章下添加补充内容、提出你的问题或回答提出的问题。
  • 使用 <code> 标签插入几行代码,对于多行代码 — 可以使用 <pre>,对于超过十行的代码 — 建议使用沙箱(plnkrJSBincodepen 等)。
  • 如果你无法理解文章中的内容 — 请详细说明。