Python正则表达式负面看后面没有失败的匹配

时间:2014-09-03 07:14:25

标签: python regex

我正在写一个正则表达式来匹配电话号码。我遇到的一个问题是一些邮政编码看起来像电话号码。例如,在巴西,邮政编码如下所示:

30.160-0131

因此,一个简单的正则表达式会将它们捕获为误报:

In [63]: re.search(r"(?P<phone>\d+\.\d+-\d+)", "30.160-0131")
Out[63]: <_sre.SRE_Match at 0x102150990>

幸运的是,这样的邮政编码通常带有一个前缀,通常意味着&#34;邮政编码&#34;,就像这样:

CEP 30.160-0131

因此,如果你看到CEP看起来像一个电话号码,那么它不是一个电话号码 - 它是一个邮政编码。我一直在尝试编写一个正则表达式来使用negative lookbehind来捕获它,但它无法正常工作。它仍然匹配:

In [62]: re.search(r"(?<!CEP )(\d+\.\d+-\d+)", "CEP 30.160-0131")
Out[62]: <_sre.SRE_Match at 0x102150eb8>

为什么它仍然匹配,如何让负面的后卫失败?

2 个答案:

答案 0 :(得分:2)

表达式匹配,因为您没有执行任何操作来锚定数字。例如:

"CEP 11.213-132"

将匹配1.213-132,因为它不会立即跟随CEP。但是你可以强制在第一个数字之前的空格或行锚点开始:

re.search(r"(?<!CEP)(?:\s+|^)(\d+\.\d+-\d+)", s)

答案 1 :(得分:1)

如果您允许匹配这些邮政编码,并且仍然只提取电话号码,则可以避免否定前瞻:

m = re.search(r"CEP \d+\.\d+-\d+|(\d+\.\d+-\d+)", s)

然后检查m.group(1)中是否有电话号码。


re.findall的小演示:

>>> import re
>>> s = "There is a CEP 30.160-0131 and a  30.160-0132 in that sentence, which repeats itself like there is a CEP 30.160-0131 and a  30.160-0132 in that sentence."
>>> m = re.findall(r"CEP \d+\.\d+-\d+|(\d+\.\d+-\d+)", s)
>>> print(m)
['', '30.160-0132', '', '30.160-0132']

从那里,你可以过滤掉空字符串。