python - Python re 中的贪婪匹配与非贪婪匹配

标签 python regex greedy non-greedy

请帮助我发现这是否是 Python (2.6.5) 中的错误、我编写正则表达式的能力或我对模式匹配的理解的错误。

(我接受可能的答案是“升级你的 Python”。)

我正在尝试解析 Yubikey token ,以允许可选的附加功能。

当我使用此正则表达式来匹配没有任何可选附加内容的标记(即仅包含与两个捕获组匹配的内容)时,匹配失败:

r'^\t?[^a-z0-9]?([cbdefghijklnrtuv1-8]{0,32})\t?([cbdefghijklnrtuv1-8]{32})\t?\r?\n?$'

但是,如果我使第一组变得非贪婪:

r'^\t?[^a-z0-9]?([cbdefghijklnrtuv1-8]{0,32}?)\t?([cbdefghijklnrtuv1-8]{32})\t?\r?\n?$'

成功了。

所以,好吧,它有效,但我认为这两个正则表达式最终结果的唯一区别是性能。

Expresso 和 Regex Coach 都喜欢这两种模式。

我错过了什么?

<小时/>

这是我正在测试的两个字符串。

没有可选的附加功能(可能会失败的附加功能):

"vvbrentlnccnhgfgrtetilbvckjcegblehfvbihrdcui"

带有可选的附加功能(到目前为止尚未失败;实际选项卡在此处显示为“_”):

"_!_8R5Gkruvfgheufhcnhllchgrfiutujfh_"
"_!1U4Knivdgvkfthrd_brvejhudrdnbunellrjjkkccfnggbdng_"
<小时/>

我尝试使用 Alex Martelli 的建议来重现它,并且它在原始 Python 环境中不会失败,所以我将重新访问我的代码(我实际上是在 yubikey-python 上进行黑客攻击);我会在大约一天后报告。

<小时/>

向大家致歉。我无法重现该问题。当它发生时,我正在通过 getpass 读取输入;我怀疑是意外的外键敲击造成了妨碍。

我要结束这个问题了。如果对这个问题投票的人希望删除他们的投票,那是公平的。

非常抱歉。

最佳答案

我建议使用 yubikey-python对于与 yubikey 的 Python 接口(interface)——但是,这是一个侧面(并且严格实用)的问题;-)。

理论上,贪婪和非贪婪之间的选择不会导致 RE 在一种情况下匹配而在另一种情况下失败——它应该只影响匹配的内容(正如您提到的性能),而不是影响匹配的内容。匹配是否成功,因为 RE 应该为此目的回溯。

问题是,我无法重现这个问题——我手头没有 yubikey ,也没有 this file 中的测试。显示两个 RE 的匹配/不匹配行为之间没有差异。

您能否发布一些失败的示例(其中一个匹配,另一个不匹配),最好通过编辑您的问题,以便我可以重现问题并尝试将其减少到最低限度?听起来可能存在 RE 错误,但如果没有可重现的情况,我无法检查它是否以及何时被修复、已经报告或什么。谢谢!

编辑OP现在发布了一个失败的示例,但我仍然无法重现:

$ py26
Python 2.6.5 (r265:79359, Mar 24 2010, 01:32:55) 
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> r1 = re.compile(r'^\t?[^a-z0-9]?([cbdefghijklnrtuv1-8]{0,32})\t?([cbdefghijklnrtuv1-8]{32})\t?\r?\n?$')
>>> r2 = re.compile(r'^\t?[^a-z0-9]?([cbdefghijklnrtuv1-8]{0,32}?)\t?([cbdefghijklnrtuv1-8]{32})\t?\r?\n?$'
... )
>>> nox="vvbrentlnccnhgfgrtetilbvckjcegblehfvbihrdcui"
>>> r1.match(nox)
<_sre.SRE_Match object at 0xcc458>
>>> r2.match(nox)
<_sre.SRE_Match object at 0xcc920>
>>> 

即,在这两种情况下,匹配都会成功,这是应该的——而且这与 OP 使用的 2.6.5 Python 版本完全相同。 OP,请在您的平台上显示这个简单命令序列的结果,并准确地告诉我们该平台是什么,因为它看起来像一个奇怪的依赖于平台的错误...谢谢!

关于python - Python re 中的贪婪匹配与非贪婪匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3382690/

相关文章:

python - Python 有类似 Java 的匿名内部类的东西吗?

python - GAE 中 SUDS 的属性错误

python - SQLAlchemy:删除多表多态性

php - 从末尾开始匹配的正则表达式

python - 如何在 Python 中解析特定子字符串旁边的值

python - 在不删除列的情况下对 DataFrame 列求和

javascript - 为什么正则表达式不能处理 header 来检查请求?

regex - sed中的非贪婪(勉强)正则表达式匹配?

algorithm - 回合制游戏的贪心算法

algorithm - 相互重叠的事件子集