在python中过滤掉电子邮件和域的最佳方法

时间:2011-11-09 22:05:07

标签: python regex email filtering email-validation

我有一个电子邮件和域名列表,我试图将其过滤为黑名单

对于电子邮件来说,这很容易,因为我可以直接比较电子邮件,但对于域名,需要匹配带有子域名的电子邮件等。

所以对于foo.com域名,我需要过滤掉

x@foo.com
x@subdomain.foo.com

这通常如何做?通过正则表达式?将电子邮件拆分为适当的字符串?

3 个答案:

答案 0 :(得分:3)

我认为最简单的方法是使用string method ends_with。此方法的工作原理如下:

>>> blacklisted = 'foo.com'
>>> email = 'x@foo.com'
>>> email.endswith('foo.com')
True
>>> email = 'x@subdomain.foo.com'
>>> email.endswith('foo.com')
True

因此,如果域名,电子邮件或其他任何以'foo.com'结尾,则返回true。如您所见,这将包括'foo.com'的所有子域。方便的是,你也可以将一个元组传递给endswith,所以如果你构建一个列入黑名单的域的元组,你可以这样做:

>>> blacklisted = ('foo.com', 'bar.com')
>>> email = 'x@bar.com'
>>> email.endswith(blacklisted)
True

这甚至可以将一些子域列入黑名单,但不能将其他子域列入黑名单。

>>> blacklisted = ('foo.com', 'bar.com', 'sub.baz.net')
>>> email_bad = 'x@sub.baz.net'
>>> email_bad.endswith(blacklisted)
True
>>> email_good = 'x@good.baz.net'
>>> email_good.endswith(blacklisted)
False

编辑:回应Avaris的评论:

为了确保您不会遇到这种情况:

>>> blacklisted = ('bar.com', 'baz.com')
>>> email = 'x@foobar.com'
>>> email.endswith(blacklisted)
True

您可以将'.bar.com''@bar.com'列入黑名单。结果是

>>> blacklisted = ('.bar.com', '@bar.com', '.baz.com', '@baz.com')
>>> email = 'x@foobar.com'
>>> email.endswith(blacklisted)
False

这显然是更多的工作。在这一点上,我会说这种方法与正则表达式是一个偏好的问题。虽然我不惜一切代价避免使用正则表达式,但它可能是你的选择。

答案 1 :(得分:1)

这是我能想到的最简单的方法:

>>> f = 'foo@subdomain.bar.com'
>>> '.'.join(f.split('.')[-2:])
'bar.com'

它不使用正则表达式,它只有一行,非常易读,它会提取域名,并且如果域名是.com,.net或其他任何内容,还有额外的好处。 / p>

然后,您只需针对列入黑名单的表格检查提取的域名。

编辑: 好的,对于.co.uk domains等人来说

>>> import re
>>> def get_addr(email_addr):
        parts = re.split(r'[\@\.]', email_addr)
        return '.'.join(parts[(-3 if parts[-2] == 'co' else -2):])
>>> get_addr('foo@subdomain.bar.com')
'bar.com'
>>> get_addr('foo@subdomain.bar.co.uk')
'bar.co.uk'
>>> get_addr('foo@bar.com')
'bar.com'

编辑: @Wilduck指出,可能存在一些用例,你想要过滤掉特定的子维基,而不是其他的(即'community.ebay.co.uk')。我想,你可能想要将特定的电子邮件地址列入黑名单而不需要单独的表(即exgirlfriend@gmail.com)。这是我的解决方案:

>>> def is_in_blacklist(addr):
...     #check if addr is in your list or db table
...     return True or False

>>> def addr_is_blacklisted(addr):
...     if not addr: return False
...     if is_in_blacklist(addr):
...         return True
...     sliced = '.'.join(addr.split('@' if '@' in addr else '.')[1:])
...     return addr_is_blacklisted(sliced)

因此,它会从头到尾解构电子邮件地址,并根据您的黑名单检查每个部分。显然,您无法通过单个查询获得答案,但如果您愿意,可以按单个电子邮件地址,子域名,域名以及一直到顶级域名进行过滤。每个电子邮件平均有3-4个查询,如果你有一个巨大的黑名单,你就不会自杀。

答案 2 :(得分:0)

怎么样

.*foo\.com$

有效吗?