Python中的正则表达式
目标:给定一个数字(这个数字可能非常长,并且大于0),我想要得到这个数字的五个最不重要的数字,同时去掉数字末尾的任何0。
我尝试用正则表达式来解决这个问题,在RegexBuddy的帮助下,我得到了这个:
[\d]+([\d]{0,4}+[1-9])0*
但是Python无法编译这个。
>>> import re
>>> re.compile(r"[\d]+([\d]{0,4}+[1-9])0*")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.5/re.py", line 188, in compile
return _compile(pattern, flags)
File "/usr/lib/python2.5/re.py", line 241, in _compile
raise error, v # invalid expression
sre_constants.error: multiple repeat
问题出在"{0,4}"后面的"+",在Python中似乎不管用(即使是在2.6版本中也是如此)。
我该如何写一个有效的正则表达式呢?
附注:我知道可以通过不断除以10来获取余数n%100000...但这次是关于正则表达式的问题。
5 个回答
小提示。我建议你用 reTest 来测试,而不是用 RegExBuddy。因为不同的编程语言有不同的正则表达式引擎。reTest 的好处在于,它可以让你直接在 Python 中快速测试正则表达式字符串。这样你就可以确保你的语法是用 Python 的正则表达式引擎测试过的。
\d{0,4}+ 是一种贪婪量词,某些正则表达式的版本(比如 .NET 和 Java)支持这种写法。但 Python 不支持贪婪量词。
在 RegexBuddy 工具中,如果你在顶部工具栏选择 Python,RegexBuddy 会告诉你 Python 不支持贪婪量词。正则表达式中的 + 会被标记为红色,并且创建标签会显示错误信息。
如果你在 RegexBuddy 的使用标签中选择 Python,RegexBuddy 会生成一段没有贪婪量词的 Python 源代码,并附上注释,说明去掉贪婪量词可能会导致不同的结果。以下是 RegexBuddy 使用问题中的正则表达式生成的 Python 代码:
# Your regular expression could not be converted to the flavor required by this language:
# Python does not support possessive quantifiers
# Because of this, the code snippet below will not work as you intended, if at all.
reobj = re.compile(r"[\d]+([\d]{0,4}[1-9])0*")
你可能做的事情是,在主工具栏选择了 Java,然后点击“复制正则表达式为 Python 字符串”。这样会得到一个格式化为 Python 字符串的 Java 正则表达式。复制菜单中的选项并不会转换你的正则表达式,它们只是将其格式化为字符串。这让你可以像将 JavaScript 的正则表达式格式化为 Python 字符串一样,以便你的服务器端 Python 脚本可以将正则表达式传递给客户端的 JavaScript 代码。
这个正则表达式有点多余。试试这个:
>>> import re
>>> re.compile(r"(\d{0,4}[1-9])0*$")
上面的正则表达式假设这个数字是有效的(比如它也会匹配“abc0123450”)。如果你真的需要验证没有非数字字符,可以用这个:
>>> import re
>>> re.compile(r"^\d*?(\d{0,4}[1-9])0*$")
总之,\d
不需要放在字符类里,而量词 {0,4}
也不需要强制贪婪(虽然额外的 +
指定了这一点,但显然 Python 并不识别这一点)。
另外,在第二个正则表达式中,\d
是非贪婪的,我认为这样可以提高性能和准确性。我还把它设置为“零个或多个”,因为我猜这正是你想要的。
我还添加了锚点,这样可以确保你的正则表达式不会匹配字符串中间的内容。不过,如果这正是你想要的(也许你是在扫描一段长文本?),可以去掉锚点。