我有一个电子邮件和域名列表,我试图将其过滤为黑名单
对于电子邮件来说,这很容易,因为我可以直接比较电子邮件,但对于域名,需要匹配带有子域名的电子邮件等。
所以对于foo.com域名,我需要过滤掉
x@foo.com
x@subdomain.foo.com
这通常如何做?通过正则表达式?将电子邮件拆分为适当的字符串?
答案 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$
有效吗?