2017-08-01 57 views
5

我正在寻找匹配特定模式的字符串中的单词。 问题是,如果单词是电子邮件地址的一部分,则应该忽略它们。正则表达式 - 匹配模式中的单词,电子邮件地址除外

为了简化“合适词”\w+\.\w+的模式 - 一个或多个字符,一个实际时段和另一系列字符。

导致问题的句子例如是a.a b.b:c.c [email protected]

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

例如:

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

我怎么能只匹配中不包含 “@” 的话呢?

+0

而不是试图得到一个聪明的正则表达式,可能首先清理字符串?第一条带\ w + @ \ w +然后处理。我使用python完成了大量的ETL工作,而且通常清理垃圾,然后拆分/处理数据更容易/更快。 – sniperd

+0

http:// www。rexegg.com/regex-best-trick.html#thetrick –

回答

2

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

首先我们必须

words = re.split(r':|\s', "a.a b.b:c.c [email protected]") 

然后过滤掉,在他们有一个@的话。

words = [re.search(r'^(([email protected]).)*$', word) for word in words] 
1

正确解析电子邮件地址与正则表达式是非常辛苦的,但你的简单情况下,使用Word的一个简单的定义〜\w\.\w和电子邮件〜any sequence that contains @,你可能会发现这个正则表达式做你需要的东西:

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

这里的诀窍不是关注下一个或上一个单词的内容,而是关注当前捕获的单词的样子。

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

1

您可以用\[email protected]\S+\.\S+和匹配和捕获你在所有其他情况下(\w+\.\w+)模式匹配的电子邮件般子。使用re.findall只返回捕获的值,并筛选出空项(他们将在re.findall结果时,有一个电子邮件匹配):

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

Python demo

查看regex demo

相关问题