贪婪与懒惰

鉴于以下输入:

aaaaaAlazyZgreeedyAlaaazyZaaaaa

我们将使用两种模式:一种是贪婪:A.*Z,一种是懒惰:A.*?Z。这些模式产生以下匹配:

  • A.*Z 产生 1 匹配:AlazyZgreeedyAlaaazyZ(例如: Regex101Rubular
  • A.*?Z 产生了 2 个匹配:AlazyZAlaaazyZ(例如: Regex101Rubular

首先关注 A.*Z 的作用。当它与第一个 A 匹配时,.*,贪婪,然后尝试匹配尽可能多的 .

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \________________________/
      A.* matched, Z can't match

由于 Z 不匹配,引擎回溯,然后 .*必须匹配少一个 .

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \_______________________/
      A.* matched, Z can't match

这种情况发生了几次,直到它最终出现:

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \__________________/
      A.* matched, Z can now match

现在 Z 可以匹配,所以整体模式匹配:

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \___________________/
      A.*Z matched

相比之下,A.*?Z 中的不情愿(懒惰)重复首先匹配尽可能少的 .,然后根据需要采取更多的 .。这解释了为什么它在输入中找到两个匹配项。

这是两种模式匹配的直观表示:

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \____/l      \______/l      l = lazy
     \_________g_________/       g = greedy

基于实例的答案所作 polygenelubricants

POSIX 标准不包括 ? 运算符,因此许多 POSIX 正则表达式引擎没有惰性匹配。虽然重构,特别是 有史以来最伟大的技巧 ,在某些情况下可能有助于匹配,但真正的懒惰匹配的唯一方法是使用支持它的引擎。