如果支持前向引用,则正则表达式(\ 2两个|(一个))+ 匹配oneonetwo。
在字符串的开头,\ 2失败。尝试另一种选择,
因此“/ 2”失败的事实意味着跳过了以下“两个”?
一个与第二个捕获组匹配,随后由第一个组匹配。
我理解“第二个捕获组”但它是如何被“第一组”匹配的?如果它匹配两次,为什么我们在最终结果中得到“oneonetwo”而不是“oneoneonetwo”?
然后重复第一组。这次,\ 2匹配第二组捕获的一个。两个然后匹配两个。通过两次重复第一组,正则表达式匹配整个主题字符串。
这个例子来自这里:
答案 0 :(得分:3)
(\2two|(one))+
对应于以下说明:
( # start recording (for capture buffer 1)
\2 # match the string that is stored in capture buffer 2
two # match "two" literally
| # or
( # start recording (for capture buffer 2)
one # match "one" literally
) # stop recording; set capture buffer 2
) # stop recording; set capture buffer 1
+ # repeat the previous thing 1 or more times
假设目标字符串为oneonetwo
。接下来会发生什么?
我们从目标字符串中的偏移量0和正则表达式的开头开始。
逻辑上,要执行的第一件事是+
;它是正则表达式中的顶级操作。它尝试重复匹配其子正则表达式(1次或更多次)。
(
开始记录捕获缓冲区1,但实际上并没有做任何事情。
\2
尝试匹配捕获缓冲区2中的字符串,但未设置捕获缓冲区2。这个行为就像一个永远不匹配的字符串,因此整个第一个选项无法匹配。
|
开始尝试第二种选择。
(
开始记录捕获缓冲区2。
我们尝试匹配one
并成功:目标字符串中偏移0处有一个one
。我们在字符串中增加位置(剩余字符:onetwo
)并继续匹配。
)
停止录音;捕获缓冲区2现在设置为one
。
)
停止录音;捕获缓冲区1现在设置为one
。
循环的第一次迭代是成功的。我们尝试匹配更多(因为这是+
所做的):
(
开始记录捕获缓冲区1(再次)。
\2
尝试匹配捕获缓冲区2中的字符串,现在是one
。这是成功的,因为目标字符串中的当前偏移量有one
。我们在字符串中增加位置(剩余字符:two
)并继续匹配。
我们尝试匹配two
并成功。我们在目标字符串中的位置现在已经到了最后。
|
看到第一个替代方案成功了;我们现在忽略了另一种选择。
)
停止录音;捕获缓冲区1现在设置为onetwo
。
这结束了循环的第二次迭代。我们再次尝试匹配更多:
(
开始记录捕获缓冲区1。
\2
尝试匹配捕获缓冲区2中的字符串,该字符串仍为one
。这失败了(目标字符串中没有剩余字符)。
|
开始尝试第二种选择。
(
开始记录捕获缓冲区2。
我们尝试匹配one
并再次失败(目标字符串中没有剩余字符)。
第二种选择无法匹配,因此整个子组失败(我们丢弃了我们为捕获缓冲区2开始的最后一次录制)。
控制权返回+
。我们匹配了循环的两次完整迭代(第三次失败)。这很好(两个是“1或更多”的完美例子)。
我们继续,到达正则表达式的末尾。这意味着整个正则表达式成功匹配。最后,捕获缓冲区1包含onetwo
,捕获缓冲区2包含one
。
具体做法是:
oneonetwo
^^^ #1
^^^ #2
^第一次迭代后。
oneonetwo
^^^^^^ #1
^^^ #2
^第二次迭代后。