贪婪/懒惰(非贪婪)/占有量词如何在内部工作?

How do greedy / lazy (non-greedy) / possessive quantifiers work internally?

我注意到有 3 种不同的 类 量词:贪婪的、惰性的(即非贪婪的)和所有格的。

我知道,粗略地说,greedy 量词尝试通过首先读取整个输入字符串来获得最长的匹配,然后如果尝试保持不变,则一个接一个地截断字符失败; lazy 量词尝试通过首先读取空字符串来获得最短的匹配,如果尝试不断失败,然后一个接一个地添加字符; 占有 量词尝试与贪婪量词相同的方式,但如果第一次尝试失败,它们将停止匹配。

但是,我不确定上述内容具体是如何实施的'internally',并希望得到澄清(希望有示例)。


例如,假设我们的输入字符串为 "fooaaafoooobbbfoo"

如果regex是"foo.*"(贪心),那么regex中的foo会不会先匹配输入字符串中的foo,然后.*读入aaafoooobbbfoo 和 'the entire string' 一样?或者 .* 会先读入 fooaaafoooobbbfoo 作为 'the entire string',然后截断 fooaaafoooobbbfoo 以尝试匹配正则表达式中的 foo?如果是后者,那么每次尝试fooaaafoooobbbfoo会从左边截断还是从右边截断?

如果我将 "foo.*" 替换为 ".*foo""foo.*foo" 作为我的正则表达式,上述问题的答案会改变吗?如果我把那些贪婪的量词改成懒惰的和所有格的呢?

如果正则表达式中有多个量词,引擎将如何处理优先级(如果重要的话)?


提前致谢!

对于你输入的字符串fooaaafoooobbbfoo.

案例 1: 当您使用此正则表达式时:

foo.*

首先记住引擎从左到右遍历这个事实。

考虑到上面的正则表达式将首先匹配输入开始处的 foo 然后 .* 将贪婪地匹配 longest 可能的匹配是 foo 之后的其余文本,直到结束。此时匹配停止,因为在您的模式中 .* 之后没有任何匹配。

案例 2: 当您使用此正则表达式时:

.*foo

这里再次 .* 将贪婪地匹配 最长 可能的匹配,然后再匹配输入的最后一个 foo

案例 3: 当您使用此正则表达式时:

foo.*foo

将首先匹配输入中找到的 foo,即开始时的 foo 然后 .* 将在匹配之前贪婪地匹配 最长 可能的匹配last foo 即输入的结尾。

案例 4: 当您将此正则表达式与惰性量词一起使用时:

foo.*?foo

将首先匹配输入中找到的 foo,即开始时的 foo 然后 .*? 将延迟匹配 最短 可能的匹配,然后再匹配next foo 这是 foo 的第二个实例,从输入中的位置 6 开始。

案例 5: 当您将此正则表达式与所有格量词一起使用时:

foo.*+foo

将首先匹配输入中找到的 foo,即开始时的 foo 然后 .*+ 使用 占有量词 ,这意味着 尽可能多次匹配,不回馈。这将贪婪地匹配 longest 可能的匹配直到结束,并且由于所有格量词不允许引擎回溯因此在部分末尾存在 foo 将导致失败,因为引擎将失败匹配最后 foo.