我正在开发一个项目,该项目从我的关注者列表中搜索特定用户的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
答案 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
在正则表达式中查找单词边界。因此,使用它为模板添加前缀和后缀将仅匹配模式。希望它有所帮助。