重复交替组内的前瞻行为

Lookahead behaviour inside repeated alternation group

(?:(?=abc)|[abc])+ 这样的正则表达式将匹配由 abc 组成的字符串,直到满足先行条件。 例如。对于字符串 acbababcaaa 它将匹配 acbab - 停在第一个 abc 的前面,但如果它过于贪婪它可能会前进到字符串的末尾。

我们可以通过在模式末尾添加 $ 来强制执行此操作 ((?:(?=abc)|[abc])+$) - 现在它实际上匹配到字符串的末尾。

当我们现在将重复更改为所有格时 ((?:(?=abc)|[abc])++$) - 它将匹配 bcaaa - 因此第一个位置,前瞻无法再匹配。

谁能解释这些行为的原因?

当你强制引擎占有式前进时,它不再回溯到第一组 (?:...)

在看到 abc 之后,整个组都存在正前瞻引擎,并期望输入字符串结束 $。它不存在,也无法回溯以尝试交替的另一侧,因此它完全失败,[abc] 之前使用的所有字符都被释放,指针被重置为整个模式的前一个起始位置的下一个字符。

你可以用原子组(?>(?=abc)|[abc])+$来写它以更明确地表达差异。这个过程继续,只要它在输入字符串中看到 abc 后跟字符串结尾 $.

就会失败

这就是 bcaaa 个字符在末尾匹配的原因,因为在 a 之后,在 bcaaa 被消耗之前,肯定不会发生前瞻。