繁体   English   中英

在python中的列表中搜索字符串

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM