【问题标题】:How get all matches using str.contains in python regex?如何在 python 正则表达式中使用 str.contains 获取所有匹配项?
【发布时间】:2020-07-19 05:17:00
【问题描述】:

我有一个数据框,我需要在其中找到与terms 匹配的所有可能匹配行。我的代码是

texts = ['foo abc', 'foobar xyz', 'xyz baz32', 'baz 45','fooz','bazzar','foo baz']
terms = ['foo','baz','foo baz']
# create df
df = pd.DataFrame({'Match_text': texts})
#cretae pattern 
pat = r'\b(?:{})\b'.format('|'.join(terms))
# use str.contains to find matchs
df = df[df['Match_text'].str.contains(pat)]

#create pattern
p = re.compile(pat)

#search for pattern in the column
results = [p.findall(text) for text in df.Match_text.tolist()]
df['results'] = results

输出是

Match_text  results
0   foo abc     [foo]
3   baz 45      [baz]
6   foo baz     [foo, baz]

其中,foo baz 还与第 6 行以及 foobaz 匹配。我需要为terms中的所有匹配获取行

【问题讨论】:

  • 想要的输出是什么?
  • 我还需要与foo baz 匹配的行,即第 6 行
  • 也许你想使用正则表达式\b(?:foo baz|foo|baz)\bDemo。请注意,foo baz 必须是交替中的第一个词。
  • 是的,你的建议工作@cary。但我不能保证每次都会自动生成正常的模式。
  • @Raghu 试试pat = r'\b(?:{})\b'.format('|'.join(sorted(terms,key=len,reverse=True))),对你有用吗?我不确定最终的行结果应该是什么,[foo baz][foo, baz, foo baz]?我对两者都有解决方案。

标签: python regex pandas dataframe


【解决方案1】:

而不是使用正则表达式模式来检查术语的存在,

#create pattern
p = re.compile(pat)

#search for pattern in the column
results = [p.findall(text) for text in df.Match_text.tolist()]

尝试像这样在文本中使用简单的术语查找。

#search for each term in the column
results = [[term for term in terms if term in text] for text in df.Match_text.tolist()]

上面的输出如下所示,

    Match_text  results
0   foo abc [foo]
3   baz 45  [baz]
6   foo baz [foo, baz, foo baz]

注意:此方法存在时间复杂度。

【讨论】:

    【解决方案2】:

    较长的替代品应该在较短的替代品之前,因此,您需要按长度按降序对关键字进行排序:

    pat = r'\b(?:{})\b'.format('|'.join(sorted(terms,key=len,reverse=True)))
    

    结果将是\b(?:foo baz|foo|baz)\b 模式。它将首先尝试匹配foo baz,然后是foo,然后是baz。如果找到foo baz,则返回匹配项,然后从匹配项的末尾开始搜索下一个匹配项,因此您不会再次将找到的foobaz与上一个匹配项匹配。

    "Remember That The Regex Engine Is Eager" 中查看更多信息。

    【讨论】:

      猜你喜欢
      • 2020-07-17
      • 1970-01-01
      • 2010-10-13
      • 2013-05-09
      • 1970-01-01
      • 1970-01-01
      • 2021-10-12
      • 2010-11-16
      • 1970-01-01
      相关资源
      最近更新 更多