从Python中的列表中搜索字符串以获得完全匹配

时间:2014-03-05 02:30:31

标签: python regex list

我正在开发一个项目,该项目从我的关注者列表中搜索特定用户的Twitter流并转发它们。下面的代码工作正常,但如果字符串出现在单词的一侧(例如,如果所需的字符串只是“man”但是他们写了“manager”,它会被转发)。我仍然对python很陌生,但我的预感是RegEx将是要走的路,但到目前为止,我的尝试已证明无用。

    if tweet["user"]["screen_name"] in friends: 
        for phrase in list:
                if phrase in tweet["text"].lower():
                    print tweet
                    api.retweet(tweet["id"])
                    return True

2 个答案:

答案 0 :(得分:2)

由于您只想匹配整个单词,让Python执行此操作的最简单方法是将推文文本拆分为单词列表,然后使用in测试每个单词是否存在。< / p>

您可以使用优化,因为位置并不重要:通过从单词列表构建集合,您可以更快地进行搜索(技术上,O(1)而不是O(n)),因为使用了快速散列访问通过集合和决定(谢谢Tim Peters,也是 Python的禅宗的作者)。

完整的解决方案是:

if tweet["user"]["screen_name"] in friends:
    tweet_words = set(tweet["text"].lower().split())
    for phrase in list:
        if phrase in tweet_words:
            print tweet
            api.retweet(tweet["id"])
            return True

这不是一个完整的解决方案。真的,你应该照顾清除前导和尾随标点符号等事情。您可以编写一个函数来执行此操作,并使用tweet文本作为参数调用它,而不是使用.split()方法调用。

鉴于优化,我发现如果短语也是一个集合,Python中的迭代可以完全避免(迭代仍然会发生,但是以C速度而不是Python速度)。因此,在下面的代码中,假设您在初始化期间执行了代码

tweet_words = set(l.lower() for l in list)

顺便说一句,list是一个变量的可怕名称,因为通过使用它,你可以使Python列表类型在其通常的名称下不可用(尽管你仍然可以使用像{{1}这样的技巧来实现它})。也许最好将其称为type([])或其他更有意义的东西,而不是现有的名称。您必须根据自己的需要调整此代码,这只是为了给您提供想法。请注意,word_list只需设置一次。

tweet_words

答案 1 :(得分:1)

如果要使用正则表达式执行此操作,请查找\b<string>\b形式的模式。在你的情况下,这将是:

pattern = re.compile(r"\bman\b")
if re.search(pattern, tweet["text"].lower()):
    #do your thing 

\b在正则表达式中查找单词边界。因此,使用它为模板添加前缀和后缀将仅匹配模式。希望它有所帮助。