我希望在字符串中找到与特定模式匹配的单词。 问题是,如果单词是电子邮件地址的一部分,则应忽略它们。
简化“正确的单词”\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']
如何只匹配不包含“@”的单词?
答案 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。