请帮我发现这是否是Python(2.6.5)中的错误,是我写正则表达式的能力,还是我对模式匹配的理解。
(我接受一个可能的答案是“升级你的Python”。)
我正在尝试解析Yubikey令牌,允许使用可选的附加功能。
当我使用此正则表达式来匹配没有任何可选附加项的令牌(即仅包含与两个捕获组匹配的内容)时,匹配失败:
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
阅读输入;我怀疑意外的外键击中了阻碍。
我将结束这个问题。如果提出问题的人希望取消投票,这是公平的。
非常抱歉。
答案 0 :(得分:3)
我建议使用yubikey-python进行与yubikey的Python接口 - 但这是一个侧面(并且是严格实用的)问题; - )。
理论上,不应该选择贪婪和非贪婪之间的选择导致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,请在您的平台上显示这个简单命令序列的结果,并告诉我们该平台究竟是什么,因为它看起来像一个奇怪的平台依赖的bug ...谢谢!
答案 1 :(得分:0)
你是对的:简单地从贪婪切换到非贪婪量词不应该导致正则表达式停止工作。它可以改变正则表达式匹配(或不匹配)的速度,它匹配的多少,以及哪些部分被捕获在哪些组中,这就是全部。
(以下“解决方案”不适用,但问题仍然没有表明正在执行不区分大小写的匹配,因此我将保留它。)
你的问题是带有可选附加功能的字符串中也包含大写字母,而你的正则表达式只允许使用小写字母。在正面或正则表达式上粘贴(?i)
,它就可以正常工作。