这个转发正则表达式示例如何工作?
如果支持前向引用,则正则表达式( 2two |(one))+会匹配oneonetwo。
在字符串的开头, 2失败。 尝试另一种选择,
那么“/ 2”失败的事实意味着下面的“两个”被跳过了?
一个由第二捕获组匹配,然后由第一组匹配。
我了解“第二捕获组”,但它如何与“第一组”匹配? 而且,如果它匹配两次,为什么我们在最终结果中得到“oneonetwo”而不是“oneoneonetwo”?
然后重复第一组。 这一次, 2匹配第二组捕获的一个。 两个然后匹配两个。 通过两次重复第一组,正则表达式匹配整个主题字符串。
这个例子来自于这里:
https://www.regular-expressions.info/backref2.html
(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
并取得成功:有一个one
在目标字符串偏移量为0。 我们在字符串中增加我们的位置(剩余字符: 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
^在第二次迭代之后。
链接地址: http://www.djcxy.com/p/12985.html上一篇: How does this forward regex example work?
下一篇: regex: get list of the locations of captured groups, not matches