【发布时间】:2017-05-10 10:19:27
【问题描述】:
这是this question 的后续。
看看这个模式:
(o(?1)?o)
它匹配任何长度为 2n 且 n ≥ 1 的 o 序列。
It works, see regex101.com(添加字边界以便更好地演示)。
问题是:为什么?
在下文中,字符串的描述(匹配与否)将只是一个粗体数字或描述长度的粗体术语,如 2n。
分解(添加空格):
( o (?1)? o )
( ) # Capture group 1
o o # Matches an o each at the start and the end of the group
# -> the pattern matches from the outside to the inside.
(?1)? # Again the regex of group 1, or nothing.
# -> Again one 'o' at the start and one at the end. Or nothing.
我不明白为什么这不匹配 2n,而是 2n,因为我会将模式描述为 *an未定义数量的o o,相互堆叠。
可视化:
没有递归,2是匹配的:
oo
一次递归,4是匹配:
o o
oo
到目前为止,很容易。
两次递归。显然是错误的,因为模式不匹配6:
o o
o o
oo
但是为什么呢?它似乎符合模式。
我的结论是,重复的不仅仅是简单的模式,否则 6 将不得不匹配。
(?P<name>[abc])(?1)(?P>name)匹配三个字母,就像(?P<name>[abc])[abc][abc]一样。
和
[abc])(?1){3}[...] 等价于([abc])[abc]{3}
所以它似乎只是简单地重新匹配正则表达式代码,而没有关于捕获组的先前匹配的信息。
有人能解释一下为什么这个模式匹配 2n 而没有别的吗?
编辑:
在cmets中提到过:
我怀疑在自身内部引用捕获组实际上是受支持的情况。
regular-expressions.info does mention the technique:
如果您在它调用的组内进行调用,您将拥有一个递归捕获组。
【问题讨论】:
-
你正确理解了递归。单词边界在这里让你感到困惑。 Look here, 6
os 匹配得很好。 -
这很有趣。你是对的,这让我很困惑。就字边界而言,6、8、12 和 16 之间的区别在哪里?我稍后会编辑问题。
标签: regex recursion pcre regex-group regex-recursion