这可能是一个愚蠢的问题,但我只是想学习!
我正在尝试构建一个简单的电子邮件搜索工具,以了解有关python的更多信息。我正在修改一些开源代码来解析电子邮件地址:
emails = re.findall(r'([A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*)', html)
然后我使用CSV模块将结果写入电子表格。
由于我想保持域扩展几乎任何一个,我的结果是输出电子邮件类型格式的图像文件:
示例:forbes@2x-302019213j32.png
如何添加以从re.findall
中排除“png”字符串代码:
def scrape(self, page): try: request = urllib2.Request(page.url.encode("utf8")) html = urllib2.urlopen(request).read() except Exception, e: return emails = re.findall(r'([A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*)', html) for email in emails: if email not in self.emails: # if not a duplicate self.csvwriter.writerow([page.title.encode('utf8'), page.url.encode("utf8"), email]) self.emails.append(email)
答案 0 :(得分:2)
你已经只对if进行了操作......只是参与if检查......这比试图从正则表达式中排除它要容易得多
if email not in self.emails and not email.endswith("png"): # if not a duplicate
self.csvwriter.writerow([page.title.encode('utf8'), page.url.encode("utf8"), email])
self.emails.append(email)
答案 1 :(得分:2)
有很多方法可以做到这一点,但我最喜欢的是:
pat = re.compile(r'''
[A-Za-z0-9\.\+_-]+ # 1+ \w\n.+-_
@[A-Za-z0-9\._-]+ # literal @ followed by same
\.png # if png, DON'T CAPTURE
|([A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*)
# if not png, CAPTURE''', flags=re.X)
由于正则表达式是从左到右计算的,如果字符串开始匹配,那么它将首先匹配|
的左侧。如果字符串以.png
结尾,那么它将使用该字符串但不捕获它。如果它不以.png
结尾,|
的右侧将开始消耗它并将捕获它。有关此技巧的更深入的对话,see here。要使用它们:
matches = filter(None,pat.findall(html))
左侧匹配的任何字符串(例如,匹配但不属于捕获组的所有png
文件)将在您的findall中显示为空字符串。 filter(None, iterable
)从您的iterable中删除所有空字符串,只留下您想要的数据。
或者,您可以在获取所有内容后进行过滤
pat = re.compile(r'''[A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*''')
# same regex you have currently
matches = filter(lambda x: not x.endswith('png'), pat.findall(html))
请注意,您应该真正设置self.emails
一套。它似乎不需要保持其排序,并且设置查找比列表查找更快。请记住使用set.add
代替list.append
。
答案 2 :(得分:2)
我知道Joran已经给了你一个回应,但是这是用Python正则表达式做的另一种方法,我觉得很酷。
有一个(?!...)
匹配模式,基本上说:“无论你在哪里放置这种匹配模式,如果在字符串中的那个点检查这个模式并找到匹配,那么该匹配发生失败。”< / p>
如果这是一个糟糕的解释,Python文档会做得更好:https://docs.python.org/2/howto/regex.html#lookahead-assertions
此外,这是一个工作示例:
y = r'([A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.(?!png)[a-zA-z]*)'
s = 'forbes@2x-302019213j32.png'
re.findall(y, s) # Will return an empty list
s2 = 'myname@email2018529391230.net'
re.findall(y, s2) # Will return a list with s2 string
s3 = s + ' ' + s2 # Concatenates the two e-mail-formatted strings
re.findall(y, s3) # Will only return s2 string in list