【问题标题】:Regular Expression Dot not working正则表达式点不起作用
【发布时间】:2017-02-13 04:29:14
【问题描述】:

所以我试图解析一个文件,我有以下代码:

def learn_re(s):
pattern=re.compile("[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} .")
if pattern.match(s):
    return True
return False

这与 "01:01:01.123 —" 匹配;但是,当我再添加一个字符时,它就不起作用了。例如,如果我编辑我的代码,使其成为

def learn_re(s):
pattern=re.compile("[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} . C")
if pattern.match(s):
    return True
return False

这与“01:01:01.123 — C”不匹配这是怎么回事?

【问题讨论】:

  • . 在正则表达式中表示任何字符。要匹配 .,请在正则表达式中使用 \.
  • 我无法重现此问题 - 第二个示例运行良好。
  • “这不匹配”字符串在您的帖子中包含一个扩展字符:em-dash。根据您的语言环境,这是一个字符,还是被认为超过 1 个? (即 UTF-8。)
  • 三个单独的字符sounds about right。您的 Python 构建不支持 Unicode。您可能想edit您的帖子并添加您正在使用的版本。
  • 是的,我后来知道了。 @JimmyKim 所以你的意思是[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} ... C 匹配第二个?

标签: python regex python-2.7


【解决方案1】:

问题在于您的 — 是一个 unicode 字符。在 str 中时,它实际上更像是几个字符:

>>> print len('—')
3

但是,如果您使用unicode 而不是str

>>> print len(u'—')
1

因此,以下将打印True

def learn_re(s):
    pattern=re.compile("[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3} . C")
    if pattern.match(s):
        return True
    return False

print learn_re(u"01:01:01.123 — C")

请注意,此行为特定于 python 2。在 python 3 中,strunicode 合并为一个 str 类型,因此不需要这种区别。

【讨论】:

    【解决方案2】:

    字符串中的破折号是 unicode 字符,将被解释为多个字符 (3 in your case)。您的 python 版本不支持 unicode,因此您需要匹配 3 个字符来捕获.{3} 破折号,完全匹配表达式中的字符,或者使用不同版本的 python。

    关于你的表达的几点说明;您应该始终在您的正则表达式字符串前面加上 r'...',以便正确解释您的 \ 转义。

    正则表达式中的. 具有特殊含义,它将匹配任何单个字符。如果需要句点/小数点,则需要转义点\.

    pattern = re.compile(r'[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3} .')
    

    【讨论】:

    • 您好,感谢您的回答,但我知道 .将匹配任何单个字符。我用它来处理长破折号。但是,我编辑的代码不应该仍然与“01:01:01.123 - C”匹配吗?
    • 这个答案确实不能解决这个问题。
    • 问题不在于只匹配文字 . 的表达式也匹配其他字符 - 恰恰相反。应该匹配的表达式没有这样做......或者OP说。它对我来说很好。
    • 这个答案的“最终”部分是实际答案。其余的都是积极的_un_helpful和误导。如果正则表达式过于严格,则使其更具限制性无济于事,并且与这种情况下的实际问题无关。回答前请仔细阅读问题。
    • 它指的是.,它匹配表达式前面的小数位,而不是破折号的小数位。虽然它在技术上是有效的,但它显然应该是文字,而不是通配符。
    猜你喜欢
    • 1970-01-01
    • 2020-07-08
    • 2015-06-19
    • 1970-01-01
    • 2016-01-31
    • 2014-12-15
    相关资源
    最近更新 更多