[英]Searching a string in a list in python
您好,我有一个包含邮件地址的字符串。 例如(user@foo.bar.com)并且我有一个列表,其中仅包含域(“ bar.com”,“ stackoverflow.com”)等。
我想搜索列表中是否包含我字符串的域。 现在我正在使用这样的代码
if tokens[1].partition("@")[2] in domainlist:
tokens [1]包含邮件地址,domainlist包含域。 但是正如您所看到的, tokens[1].partition("@")[2]
将返回foo.bar.com
但我的列表具有bar.com
域。 如果语句返回true,我该如何做呢? 而且它应该非常快,因为每秒会收到数百个邮件地址
它应该像这样工作:
if any(tokens[1].endswith(domain) for domain in domainlist):
如果速度确实是您的问题,则可以研究Aho-Corasick之类的方法。 有很多实现的程序,比如esmre
/ esm
http://code.google.com/p/esmre/
正如@Riccardo Galli指出的那样,简单的字符串匹配会产生一些误报,因此您可以首先尝试使用esmre
,将符合条件的正则表达式添加到索引中,例如index.enter("(^|\\.){0}$".format(domain))
首先,将domainlist
一组。 检查其中是否包含某些东西会更快。
其次,将所有“超级域”添加到该集合中,例如“ foo.bar.com”的“ bar.com”。
domainlist = ['foo.bar.com', 'bar2.com', 'foo3.bar3.foobar.com']
domainset = set()
for domain in domainlist:
parts = domain.split('.')
domainset.update('.'.join(parts[i:]) for i in xrange(len(parts)-1))
#domainset is now:
set(['bar.com',
'bar2.com',
'bar3.foobar.com',
'foo.bar.com',
'foo3.bar3.foobar.com',
'foobar.com'])
现在您可以测试
if tokens[1].partition("@")[2] in domainset:
数百个邮件地址应该不是问题。 以下是单线:
any(domain.endswith(d) for d in MY_DOMAINS)
在这里,您可以执行user,sep,domain = address.rpartition('@')
。 否则,您的当前方法对于诸如"B@tm4n"@something.com
电子邮件地址将失败,该电子邮件地址根据http://tools.ietf.org/html/rfc5322有效
如果性能成为一个因素,则可以使用Trie(一种数据结构)。 如果性能仍然是一个因素,则可以使用其他技巧。
上面的内容遍历了您要检查的域中的每个元素,因此,如果列表中有1000个域,则需要为每个电子邮件地址进行1000次查找。 如果这是一个问题,则可以执行此操作以使每次查找达到O(1)
(您可能还希望确保您检查的后缀不超过5个,以保护自己免受恶意制作的电子邮件地址的侵害)。
MY_DOMAINS = set(MY_DOMAINS)
def suffixes(domain):
"""
suffixes('foo.bar.com') -yields-> ['foo.bar.com', 'bar.com', 'com']
"""
while True:
yield domain
parts = domain.split('.',1)
if len(parts>1)
domain = parts[1]
else:
break
def isInList(address):
user,sep,domain = address.rpartition('@')
return any(suffix in MY_DOMAINS for suffix in suffixes(domain))
与其他答案相反,此处的“ foo.com”也不会与“ @ y.afoo.com”匹配
def mailInDomains(mail,domains):
for domain in domainList:
dLen = len(domain)
if mail[-dLen:]==domain and mail[-dLen-1] in ('.','@'):
return True
return False
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.