【发布时间】:2018-10-22 23:46:32
【问题描述】:
在 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()
但在我的实际用例中,中间组是一个长几个字符的字符串,其中任何一个都可能单独出现在左侧或右侧组中,所以我不能只从左侧或右侧排除这些字符组。
我查看了标记为regex-greedy 的其他问题,但似乎没有人回答这个问题,尽管我怀疑 ctwheels 在python non-greedy match 中的回复是我的问题的原因(前两组的可选性阻止了正则表达式引擎从实际失败直到它到达字符串的末尾,然后它只需要回溯一些方法来获得非失败匹配)。
【问题讨论】:
-
(.*?)将匹配下一个可能匹配的内容。 ` (b?)` 将不匹配任何内容,这足以在第一个字符之前终止惰性匹配。这没什么。 -
谢谢,感谢艾哈迈德的回答,我现在更好地理解了这一点,并且我已经实现了 s.t.这类似于 tdelaney 的答案(主要是因为我想避免前瞻,我可能直觉不到我直觉的懒惰/贪婪搜索)。答案选哪个?我选择艾哈迈德的,因为虽然两种解决方案都有效,艾哈迈德更好地解释了问题。但是感谢你们俩!
标签: regex-greedy regex python-3.x regex-greedy