我正在写一个正则表达式来匹配电话号码。我遇到的一个问题是一些邮政编码看起来像电话号码。例如,在巴西,邮政编码如下所示:
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>
为什么它仍然匹配,如何让负面的后卫失败?
答案 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']
从那里,你可以过滤掉空字符串。