将正则表达式放在小括号内,强调该部分是一个整体,即子表达式。子表达式用来定义字符或表达式的集合。除了可以用在重复匹配操作中,还可以在模式的内部以外子表达式被引用,这种引用被称为回溯引用。
问题
为了理解回溯引用的概念,先来看一个比较简单的例子,这个问题如果不使用回溯引用将根本无法解决。
假设你有一段文本,你想把这段文本里所有连续重复出现的单词(打字错误,其中有一个单词输了两遍)找出来。显然,在搜索某个单词的第二次出现时,这个单词必须是已知的。回溯引用允许正则表达式模式引用前面的匹配结果(具体到这个例子,就是前面匹配到的单词)。
解决办法
把这个问题弄明白的最佳办法是看它到底是如何工作的。下面是一段包含着3组重复单词的文本,它们就是我们要找的东西:
文本
This is a block of of text several words here are are repeated, and and they should not be.
正则表达式
/\s+(\w+)\s+\1/g
结果
This is a block of of text several wordshere are are repeated, and and they should not be.
这个模式找到了我们想要的东西,但它是如何做到这一点的呢 ?\s+
匹配一个或多个空格,\w+
匹配一个或多个字母数字字符,\s+
匹配随后的空格。
注意点
\w+
是放在括号里的,它是一个子表达式。这个子表达式不是用来进行重复匹配的,这里根本不涉及重复匹配的问题。这个子表达式只是把整个模式的一部分单独划分出来以便在后面引用。这个模式的最后一部分是\1是一个回溯引用,而它引用的正是前面划分出来的那个子表达式(\w+)
。当(\w+)
匹配到单词of
的时候,\1
也匹配单词of
;当(\w+)
匹配到单词and
的时候,\1
也匹配单词and
。- 回溯引用指的是模式的后半部分引用在前半部分中定义的子表达式(如上例所示)。
\1
到底代表着什么?它代表着模式里的第 1 个子表达式,\2
代表着第 2 个子表达式、\3
代表着第 3 个,依次类推。上述示例中,\s+(\w+)\s+\1
将匹配同一个单词的连续两次重复出现。
-我们可以把回溯引用想象成变量。
-回溯引用在文本替换操作里也非常有用。比如 replace
函数的第二个参数就可以使用回溯引用。不过要使用 $1、$2、…$n
这种语法。
评论 (0)