gpt4 book ai didi

regex - 无法进行非贪婪匹配

转载 作者:行者123 更新时间:2023-12-01 03:13:44 25 4
gpt4 key购买 nike

在 Python3.4 中,我使用了 re 库(regex 库给出了相同的结果),并且得到了我不期望的结果。

我有一个字符串 s = 'abc'。我希望以下正则表达式:

re.match(r"^(.*?)(b?)(.*?)$", s).groups()

.. 匹配三个非空组,即:
('a', 'b', 'c')

--因为模式的中间部分是贪婪的 (b?) .相反,只有最后一组是非空的:
('', '', 'abc')

我得到了以下两个相同的结果:
re.match(r"^(.*?)(b?)(.*?)$", s).groups()   #overt ^ and #
re.fullmatch("(.*?)(b?)(.*?)", s).groups() #fullmatch()

如果我让第一组成为贪婪匹配,那么结果是:
('abc', '', '')

我想我会期望的,因为贪婪 .*在其他组看到它之前消耗整个字符串。

我试图构建的正则表达式当然比这更复杂,否则,我可以排除 b来自左组和右组:
re.match(r"^([^b]*?)(b?)([^b]*?)$", s).groups()

但在我的实际用例中,中间组是一个几个字符长的字符串,其中任何一个都可能单独出现在左侧或右侧组中,因此我不能只从左侧或右侧组中排除这些字符。

我查看了其他标记为 的问题,似乎没有人回答这个问题,尽管我怀疑 ctwheels 在 python non-greedy match 中的回复是我的问题的背后(前两组的可选性防止正则表达式引擎实际失败,直到它到达字符串的末尾,然后它只需要回溯一些方法来获得非失败的匹配)。

最佳答案

I would expect the following regex

re.match(r"^(.*?)(b?)(.*?)$", s).groups()

to match with three non-empty groups.. because the middle part of the pattern is greedy



不,你不应该期望那样。实际上,由于以下原因,这种行为非常值得期待:

你特意指示第一组正则表达式偷懒 ,这意味着它将接受尽可能少的字符(在这种情况下为零),因为没有其他东西强制它寻找更多。因此,尽管第二组中的正则表达式是贪婪的(即 b? ),但它仍然无法匹配 b因为位置仍然是0。

您可以通过用 (.?) 替换您的第二组来确认这一点。在这种情况下,它将匹配 a ,而不是 b就像你可能期望的那样。这是 a demo^(.*?)(.?)(.*?)$ .

现在,如果您的规则不允许缺少 b ,您可以轻松地将正则表达式更改为 ^(.*?)(b)(.*?)$ ,但由于您希望第一组继续匹配 b存在 但同时 , b允许不存在(即第二组实际上可以为空),则此解决方案不能解决问题。

目前我想到的唯一满足这两个条件的解决方案是使用 Lookahead判断是否 b存在与否。下面是一个例子:
^((?:.*?(?=b))|.*?)(b?)(.*?)$

Try it online .

这将继续匹配任何字符(使用 . ),直到找到 b然后停止,否则(即,如果没有 b ),只要找到尽可能少的字符,它就会停止匹配(这是原始行为)。换句话说,只要 b就可以保证第二组不为空。存在。

如果这不符合您的任何条件,请告诉我。

关于regex - 无法进行非贪婪匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50311291/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com