正则表达式 - 匹配模式中的单词,电子邮件地址除外

时间:2017-08-01 15:11:31

标签: python regex negative-lookahead negative-lookbehind

我希望在字符串中找到与特定模式匹配的单词。 问题是,如果单词是电子邮件地址的一部分,则应忽略它们。

简化“正确的单词”\w+\.\w+的模式 - 一个或多个字符,一个实际句点和另一系列字符。

例如,导致问题的句子是a.a b.b:c.c d.d@e.e.e

目标是仅匹配[a.a, b.b, c.c]。对于我构建的大多数正则表达式,e.e也会返回(因为我使用了一些单词边界匹配)。

例如:

>>> re.findall(r"(?:^|\s|\W)(?<!@)(\w+\.\w+)(?!@)\b", "a.a b.b:c.c d.d@e.e.e") ['a.a', 'b.b', 'c.c', 'e.e']

如何只匹配不包含“@”的单词?

3 个答案:

答案 0 :(得分:2)

我肯定会先清理它并简化正则表达式。

首先我们有

words = re.split(r':|\s', "a.a b.b:c.c d.d@e.e.e")

然后过滤掉其中包含@的字词。

words = [re.search(r'^((?!@).)*$', word) for word in words]

答案 1 :(得分:1)

使用正则表达式正确解析电子邮件地址非常困难,但对于简化的情况,使用单词〜\w\.\w和电子邮件〜any sequence that contains @的简单定义,您可能会发现此正则表达式可以执行的操作你需要:

>>> re.findall(r"(?:^|[:\s]+)(\w+\.\w+)(?=[:\s]+|$)", "a.a b.b:c.c d.d@e.e.e")
['a.a', 'b.b', 'c.c']

这里的诀窍不是关注下一个或上一个词中的内容,而是关注当前捕获的词必须是什么样的。

另一个技巧是正确定义单词分隔符。 之前这个词我们将允许多个空格,:和字符串开始,消费这些字符,但不捕获它们。 后我们要求的字几乎相同(字符串结束,而不是开头),但我们不消耗这些字符 - 我们使用前瞻断言。

答案 2 :(得分:1)

您可以将类似电子邮件的子字符串与\S+@\S+\.\S+匹配,并在所有其他上下文中使用(\w+\.\w+)匹配并捕获您的模式。使用re.findall仅返回捕获的值并过滤掉空项(当电子邮件匹配时,它们将显示在re.findall个结果中):

import re
rx = r"\S+@\S+\.\S+|(\w+\.\w+)"
s = "a.a b.b:c.c d.d@e.e.e"
res = filter(None, re.findall(rx, s))
print(res)
# => ['a.a', 'b.b', 'c.c']

请参阅Python demo

请参阅regex demo