Python中的正则表达式

1 投票
5 回答
8086 浏览
提问于 2025-04-15 12:15

目标:给定一个数字(这个数字可能非常长,并且大于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 个回答

2

小提示。我建议你用 reTest 来测试,而不是用 RegExBuddy。因为不同的编程语言有不同的正则表达式引擎。reTest 的好处在于,它可以让你直接在 Python 中快速测试正则表达式字符串。这样你就可以确保你的语法是用 Python 的正则表达式引擎测试过的。

5

\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 代码。

10

这个正则表达式有点多余。试试这个:

>>> 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 是非贪婪的,我认为这样可以提高性能和准确性。我还把它设置为“零个或多个”,因为我猜这正是你想要的。

我还添加了锚点,这样可以确保你的正则表达式不会匹配字符串中间的内容。不过,如果这正是你想要的(也许你是在扫描一段长文本?),可以去掉锚点。

撰写回答