正则表达式中不匹配的可选字符串

时间:2010-12-09 13:08:28

标签: python regex

字符串s更大,但我已缩短它以简化。

>>> import re
>>> s = "Blah. Tel.: 555 44 33 22."
>>> m = re.search(r"\s*Tel\.:\s*(?P<telephone>.+?)\.", s)
>>> m.group("telephone")
'555 44 33 22'

上面的代码有效,但是如果我将正则表达式包装在()?中以使其可选,我就不会接到任何电话。

>>> m = re.search(r"(\s*Tel\.:\s*(?P<telephone>.+?)\.)?", s)
>>> m
<_sre.SRE_Match object at 0x9369890>
>>> m.group("telephone")

这里有什么问题?谢谢!

修改

这是一个更大的正则表达式的一部分,我从一个大文件的每一行得到很多值。

regex = r"^(?P<title>.[^(]+);" \
         "\s*(?P<subtitle>.+)\." \
         "\s*Tel\.:\s*(?P<telephone>.+?)(\.|;)" \
         "\s*(?P<url>(www\.|http://).+?\.[a-zA-Z]+)(\.|;)" \
         "(\s*(?P<text>.+?)\.)?" \
         "\s*coor:(\s*(?P<lat>.+?),\s*(?P<long>.+?))?$"

一个样本行可能是:

l = "Title title; Subtitle, subtitle. Tel.: 555 33 44 11. www.url.com. coor: 11.11111, -2.222222

和其他样本行:

l = "Title2 title; Subtitle2, subtitle. Tel.: 555 33 44 11. www.url2.com. coor: 44.444444, -6.66666

这是一个非常大的正则表达式,所以这就是我没有发布它的原因。

3 个答案:

答案 0 :(得分:2)

(anything)?匹配字符串最开头的零字符串(Blah之前),所以很高兴并且不会进一步搜索。

编辑:

如果您有许多行,并且只有部分行包含所需的字符串,请尝试以下操作:

import re

rex = re.compile(r"\s*Tel\.:\s*(?P<telephone>.+?)\.")
for line in lines:
    m = rex.search(line)
    if m:
        print m.group("telephone")

答案 1 :(得分:2)

这是因为空字符串是正则表达式的有效匹配,并且优先于较长的匹配。

您可能需要查看re.findall

编辑:您可以完全从正则表达式中移除选项:

import re
s = "Blah. Tel.: 555 44 33 22."
m = re.search(r"\s*Tel\.:\s*(?P<telephone>.+?)\.", s)
if m is not None:
  print m.group("telephone")

答案 2 :(得分:0)

你的正则表达式在titlesubtitle位匹配时太不明确了。他们正在吞噬电话部分,如果这是可选的,它将继续在正则表达式的下一部分(并成功)。只有当它不是可选的时,正则表达式引擎才能回溯,以便找到整体匹配。

尝试

regex = r"^(?P<title>[^;]+);" \
         "\s*(?P<subtitle>[^.]+)\." \
         "(\s*Tel\.:\s*(?P<telephone>.+?)(\.|;))?" \
         "\s*(?P<url>(www\.|http://).+?\.[a-zA-Z]+)(\.|;)" \
         "(\s*(?P<text>.+?)\.)?" \
         "\s*coor:(\s*(?P<lat>.+?),\s*(?P<long>.+?))?$"