1

目标:给定一个数字(它可能很长并且大于 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 中)

我怎样才能编写一个有效的正则表达式?

PS:我知道你可以开始除以 10,然后使用余数 n%100000 ......但这是关于正则表达式的问题。

4

5 回答 5

10

那个正则表达式是非常多余的。试试这个:

>>> import re
>>> re.compile(r"(\d{0,4}[1-9])0*$")

上面的正则表达式假设数字是有效的(例如,它也会匹配“abc 012345 0”。)如果你真的需要验证没有非数字字符,你可以使用这个:

>>> import re
>>> re.compile(r"^\d*?(\d{0,4}[1-9])0*$")

无论如何,\d不需要在字符类中,并且量词{0,4}不需要被强制为贪婪(正如附加+指定的那样,尽管显然 Python 不承认这一点。)

此外,在第二个正则表达式中,\d是非贪婪的,因为我相信这将提高性能和准确性。我也把它设为“零或更多”,因为我认为这就是你想要的。

我还添加了锚点,因为这样可以确保您的正则表达式不会匹配字符串中间的任何内容。如果这是您想要的(也许您正在扫描长文本?),请移除锚点。

于 2009-06-15T15:02:28.613 回答
5

\d{0,4}+ 是某些正则表达式风格(如 .NET 和 Java)支持的所有格量词。Python 不支持所有格量​​词。

在 RegexBuddy 中,在顶部工具栏中选择 Python,RegexBuddy 会告诉您 Python 不支持所有格量​​词。+ 将在正则表达式中以红色突出显示,并且 Create 选项卡将指示错误。

如果您在 RegexBuddy 的 Use 选项卡上选择 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,然后单击 Copy Regex as Python String。这将为您提供一个格式化为 Pythong 字符串的 Java 正则表达式。复制菜单中的项目不会转换您的正则表达式。他们只是将其格式化为字符串。这允许您执行诸如将 JavaScript 正则表达式格式化为 Python 字符串之类的操作,以便您的服务器端 Python 脚本可以将正则表达式馈送到客户端 JavaScript 代码中。

于 2009-06-16T14:38:24.160 回答
2

小提示。我建议您使用reTest而不是 RegExBuddy 进行测试。不同的编程语言有不同的正则表达式引擎。ReTest 的价值在于它允许您在 Python 本身内快速测试正则表达式字符串。这样您就可以确保您使用 Python 的正则表达式引擎测试了您的语法。

于 2009-06-15T14:56:55.303 回答
0

错误似乎是您连续有两个量词,{0,4} 和 +。除非 + 在这里是一个文字(我怀疑,因为你在谈论数字),那么我认为你根本不需要它。除非它在这种情况下意味着不同的东西(可能是 {} 量词的贪婪)?我会尝试

[\d]+([\d]{0,4}[1-9])0*

如果您实际上打算同时应用两个量词,那么这可能会起作用

[\d]+(([\d]{0,4})+[1-9])0*

但是鉴于您对问题的说明,我怀疑这就是您想要的。

于 2009-06-15T15:02:18.070 回答
0

这是我的解决方案。

re.search(r'[1-9]\d{0,3}[1-9](?=0*(?:\b|\s|[A-Za-z]))', '02324560001230045980a').group(1)

'4598'

  • [1-9]- 数字必须以 1 - 9 开头
  • \d{0,3}- 0 或 3 位数字
  • [1-9]- 数字必须以 1 或 9 结尾
  • (?=0*(:?\b|\s\|[A-Za-z]))- 字符串的最后部分必须由 0 和或\b, \s,组成[A-Za-z]
于 2012-09-13T10:13:53.760 回答