正则表达式的"贪婪"如何工作



这是一个非常简单的正则是: -

kabk
k(.*)k
result:
kabk has 1 group:
ab

我通常要做的就是以下内容,这是对的,但不必要。

k([^k]*)k

谁能向我解释正则表达式解析器的工作方式?.*是否应该尽可能多地消耗。

是的,*操作员很贪婪,将捕获尽可能多的有效字符。

例如,应用于kkkkak的模式k(.*)k将捕获kkka

您可以使用?操作员制作操作员非怪兽。

因此,应用于 kkkkak的模式k(.*?)k将捕获 nothing ,因为最小的非怪兽匹配是在前两个k字符之间允许什么都不允许。

在回复您的评论时,模式中最终的k的存在意味着它需要尽可能多地离开 k

kabk中,只有两个k s。因此,了解贪婪的比赛是不合适的例子。

让我们以其他示例尝试一下: kabkxyk

贪婪的版本匹配返回kabkxyk.*上次k之前的进步):( Followng是JavaScript):

'kabkxyk'.match(/k.*k/)
// ["kabkxyk"]

非怪兽版本匹配返回kabk

'kabkxyk'.match(/k.*?k/)
// ["kabk"]

让我们在regex101.com debugger上首先查看 k([^k]*)k(使用否定匹配)::

1   /k([^k]*)k/ kabk
2   /k([^k]*)k/ kabk
3   /k([^k]*)k/ kabk
4   /k([^k]*)k/ kabk
5   /k([^k]*)k/ kabk
6   /k([^k]*)k/ kabk
7   /k([^k]*)k/ kabk
#   Match found in 7 steps.

现在让我们在同一Regex101.com上查看k(.*)k(使用Geedy匹配匹配)调试器:

1   /k(.*)k/ kabk
2   /k(.*)k/ kabk
3   /k(.*)k/ kabk
4   /k(.*)k/ kabk
5   /k(.*)k/ kabk
6   /k(.*)k/ kabk BACKTRACK
7   /k(.*)k/ kabk BACKTRACK
8   /k(.*)k/ kabk
9   /k(.*)k/ kabk
#   Match found in 9 steps.

显然,首先在较长的字符串中更有效地提高了涉及的回溯。

是的, .*是贪婪的。它与它尽可能地匹配。

.*?是非绿色的,也不是怪异的。它匹配尽可能少。

如果您将"香蕉"与ba.*a匹配,则它将与banana匹配。

如果将"香蕉"与ba.*?a匹配,则它将匹配bana

最新更新