用#找到所有单词

时间:2017-12-02 16:53:00

标签: python

我想找到所有附有#的单词。 我试过了:

import re
text = "I was searching my #source to make a big desk yesterday."
re.findall(r'\b#\w+', text)

但它不起作用......

3 个答案:

答案 0 :(得分:2)

这是一个小的正则表达式:

>>> import re
>>> s = "I was searching my #source to make a big desk yesterday."
>>> re.findall(r"#(\w+)", s)
['source']

如果要包含主题标签,请使用:

>>> re.findall(r"#.\w+", s)
['#source']

答案 1 :(得分:1)

您可以使用:

re.findall(r"#.+?\b", text)

给出:

['#source']

这是regex101的链接,可以深入了解每个部分的作用。

基本上发生的事情是:

  • #表示从字面上捕获'#'字符
  • 然后我们说要匹配任何字符.
  • +表示捕获一个或多个
  • 然后?开始与以下任何内容的非贪婪匹配
  • \b是一个字边界,表示何时停止查找

<强>更新

正如@AnthonySottile所指出的那样,上述regex会失败,即:

hello#fred

在不应该匹配时进行匹配。

要解决此问题,可以在/s的前面添加regex,以确保#位于某个空格之后,但是在这种情况下会失败其中hashtag恰好位于字符串的开头。 /b也不足以使#使主题标签不算作单词。

所以,为了解决这些问题,我提出了这个相当丑陋的解决方案,即在执行findall之前在字符串的开头添加一个空格:

re.findall(r"\s(#.+?)\b", " " + text)

我知道这不是很整洁,但确实没有其他方法可以做到。我尝试在开始时使用OR来匹配空格或字符串的开头,如(^|\s)中所示,但这将在列表中生成多个组(作为元组),从{{ 1}}所以需要一些后处理,甚至更少整洁。

答案 2 :(得分:1)

您不需要正则表达式来解决此问题:

text = "I was searching my #source to make a big desk yesterday."
final_text = [i for i in text.split() if i.startswith('#')]

输出:

['#source']

然而,这个正则表达式将起作用:

import re
text = "I was searching my #source to make a big desk yesterday."
final_text = filter(lambda x:x, re.findall('(?<=^)|(?<=\s)#\w+(?=\s)|(?=$)', text))

输出:

['#source']