需要帮助了解如何在Python中使用不那么复杂的正则表达式

时间:2008-12-11 23:41:55

标签: python regex

我正在努力学习更多有关正则表达式的信息,我在下面有一个我认为可以找到一个数字高达999亿的错误关闭的情况。我认为它下面的那个应该做同样但我没有得到类似的结果

   missingParenReg=re.compile(r"^\([$]*[0-9]{1,3}[,]?[0-9]{0,3}[,]?[0-9]{0,3}[,]?[0-9]{0,3}[.]*[0-9]*[^)]$")
   missingParenReg2=re.compile(r"^\([$]?([0-9]{1,3}[,]?)+[.]*[0-9]*[^)]$")

我认为第二个说: 必须有一个开放的paren开始 可能有也可能没有多达一美元的符号
下一组必须至少存在一次,但可以无限次存在 该组应该至少有一个数字,但可能有多达三个数字 该组可能只有0和多达1个逗号 在此组之后可能会有或可能没有小数点
如果有一个小数点,它将跟随多达0,但与数字的无数次出现一样多 最后不应该有一个闭幕式。

我正在尝试理解这些神奇的东西,所以如果你拥有它,除了更优雅的解决方案之外,我还要感谢对我的正则表达式进行修正(如果可以纠正)。

4 个答案:

答案 0 :(得分:4)

是否有嵌套括号(你的正则表达式假定没有)?如果不是:

whether_paren_is_missing = (astring[0] == '(' and not astring[-1] == ')')

验证美元金额部分:

import re

cents = r"(?:\.\d\d)" # cents 
re_dollar_amount = re.compile(r"""(?x)
    ^               # match at the very begining of the string
    \$?             # optional dollar sign
    (?:               # followed by
        (?:             # integer part  
        0               # zero
        |               # or
        [1-9]\d{,2}     # 1 to 3 digits (no leading zero) 
        (?:               # followed by
            (?:,\d{3})*     # zero or more three-digits groups with commas                          
            |               # or
            \d*             # zero or more digits without commas (no leading zero)
            )
        )
        (?:\.|%(cents)s)?   # optional f.p. part 
    |               # or
    %(cents)s       # pure f.p. '$.01'
    )
    $               # match end of string
    """ % vars())

允许:

    $0
    0
    $234
    22
    $0.01
    10000.12
    $99.90
    2,010,123
    1.00
    2,103.45
    $.10
    $1.

禁止:

    01234
    00
    123.4X
    1.001
    .

答案 1 :(得分:3)

关于正则表达式的棘手部分并不是让它们接受有效输入,而是让它们拒绝无效输入。例如,第二个表达式接受明显错误的输入,包括:

  • (1,2,3,4 - 每个逗号之间的一位数
  • (12,34,56 - 每个逗号之间的两位数
  • (1234......5 - 无限小数点数
  • (1234,.5 - 小数点前的逗号
  • (123,456789,012 - 如果有逗号,则应在每个三元组之间
  • (01234 - 领先的零不是传统的
  • (123.4X - 最后一个字符不是结束语paren

这是一个可以拒绝上述示例的替代正则表达式:

[-+]?[$]?(0|[1-9]\d*|[1-9]\d{0,2}(,\d{3})*)(\.\d+)?

  • 可选领先加/减。
  • 可选的美元符号。
  • |分隔的三个选项:
    • 单个零数字(对于0.5或0的数字)。
    • 任意数字的数字,没有逗号。第一个数字不能为零。
    • 以逗号分隔的数字。第一个数字不能为零。第一个逗号前最多三位数。每个逗号后面必须跟上正好三位数。
  • 可选的单个小数点,后面必须跟一个或多个数字。

关于parens,如果你关心的是parens是否平衡,那么你可以忽略解析数字格式;只相信parens之间的任何数字,小数点和逗号组合都是有效的。然后使用(?!...)构造作为匹配,如果输入匹配里面的正则表达式。

(?!\([$\d.,]+\))

答案 2 :(得分:0)

我发现在定制正则表达式时使用kiki非常有帮助。它直观地向您显示正则表达式的内容。这是一个巨大的节省时间。

答案 3 :(得分:-1)

我一眼就看出的一个区别是你的正则表达式找不到像这样的字符串:

(123,,,

这是因为更正后的版本要求逗号之间至少有一位数字。 (合理的要求,我会说。)