Python regex负lookbehind不匹配

2024-06-01 01:10:51 发布

您现在位置:Python中文网/ 问答频道 /正文

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

30.160-0131

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

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

幸运的是,这些邮政编码通常带有前缀,通常表示“邮政编码”,如下所示:

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>

为什么它仍然匹配,我怎么能得到负面的看后面失败的比赛?你知道吗


Tags: inresearchmatchphone电话号码out阳性
2条回答

如果您允许匹配这些邮政编码,并且仍然只提取电话号码,则可以避免出现负面表情:

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']

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

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

"CEP 11.213-132"

将匹配1.213-132,因为它不会紧跟在CEP之后。但您可以强制空格或行锚的开头正好位于第一个数字之前:

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

相关问题 更多 >