【问题标题】:Regex in PythonPython中的正则表达式
【发布时间】:2010-11-03 01:12:21
【问题描述】:

目标:给定一个数字(它可能很长并且大于 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...但这是关于正则表达式的问题。

【问题讨论】:

  • 实际上,我认为 + 根本不应该在那里。
  • 尝试用 \1 替换。用足够长的数字在 RegexBuddy 上测试一下,你会发现区别
  • 啊,Blixt 的回答提到 + 应该是强制 {0,4} 贪婪的修饰符。我不记得以前见过那种语法——显然 Python 也没有。 (在 Java 中,它显然使 {0,4} “占有”而不是贪婪。)
  • 啊,确实如此,它迫使它变得比贪婪还多。 + 告诉引擎永远不要回溯,就像默认情况下那样。所以这并不是真正的贪婪。所有格是正确的定义 =)

标签: python regex regexbuddy


【解决方案1】:

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

【讨论】:

  • 最终,您使用的任何正则表达式都必须在您的实际应用程序中根据您的实际数据进行测试。只要正确使用工具(在这种情况下,使用 Python 时,请在 RegexBuddy 的工具栏中选择 Python),在构建正则表达式时在 RegexBuddy 等工具中运行初始测试可以节省您的时间。
【解决方案2】:

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

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

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

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

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

【讨论】:

  • 量词后面的“+”表示它是体格的。 Python 不支持姿势限定符。
【解决方案3】:

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

>>> 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 是非贪婪的,因为我相信这会提高性能和准确性。我还把它设为“零或更多”,因为我认为这就是你想要的。

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

【讨论】:

    【解决方案4】:

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

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

    如果您在 RegexBuddy 中的 Use 选项卡上选择 Python,RegexBuddy 将生成一个 Python 源代码 sn-p,其中包含一个不带所有格量词的正则表达式,以及一条表示删除所有格量词可能会产生不同结果的注释。这是 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 字符串。这将为您提供一个格式化为 Pythong 字符串的 Java 正则表达式。复制菜单中的项目不会转换您的正则表达式。他们只是将其格式化为字符串。这允许您执行诸如将 JavaScript 正则表达式格式化为 Python 字符串之类的操作,以便您的服务器端 Python 脚本可以将正则表达式馈送到客户端 JavaScript 代码中。

    【讨论】:

    • 哦,学校有一个很旧的版本,刚在家里下载了新的,有工具栏 :D 谢谢!
    • 我的回复适用于 RegexBuddy 3.0.0 及更高版本。 3.0.0 版于 2007 年 6 月 13 日发布。这是第一个可以模拟不同正则表达式风格的版本(目前是 15 版)。
    【解决方案5】:

    这是我的解决方案。

    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] 组成

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      • 2011-08-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多