使用Python进行组合词匹配的正则表达式

时间:2018-08-15 16:39:01

标签: python regex

尝试在给定的文本中找到多个单词匹配项,例如:

text = "oracle sql"
regex = "(oracle\\ sql|sql)"
re.findall(regex,text,re.I)

实际输出

  

oracle sql

预期产量

  

oracle sql,sql

谁能告诉我,正则表达式的表达在哪里?

已更新:

@jim,如果出现多个重叠,则将不起作用,例如:

re.findall("(?=(spark|spark sql|sql))","spark sql",re.I)

实际输出

  

['spark','sql']

预期输出:

  

['spark','sql','spark sql']]

注意:在上述情况下,如果两者都匹配,则不会匹配单词组合。

已更新:

检查链接:repl.it/repls/NewFaithfulMath

1 个答案:

答案 0 :(得分:3)

您不需要转义空格。

import re
text = "oracle sql"
regex = "(oracle sql|sql)"
print re.findall(regex, text, re.I)

来自documentation

  

以字符串的形式返回字符串中所有不重复的模式匹配项   字符串。

这被视为重叠匹配。

返回重叠的匹配项

您可以使用前瞻性捕获所要查找的字符串,但是由于在前瞻性上技术上是匹配的,因此它们不会重叠。

import re
text = "oracle sql"
regex = "(?=(oracle sql|sql))"
print re.findall(regex, text, re.I)

输出:

['oracle sql', 'sql']

See it in action

此实现的缺点是,它将只为字符串中特定位置的每个单词找到1个匹配项。这是由于匹配项重叠造成的。

例如(my test|my|test)只会找到['my test', 'test']

您始终可以使用正则表达式替换来查找重叠的匹配项,例如regex,但这仍然只能找到['my test', 'test'],其模式为(my test|my|test)

import regex as re
text = "oracle sql"
regex = "(oracle sql|sql)"
print re.findall(regex, text, re.I, overlapped=True)

递归

正则表达式每个字符只能找到一个匹配项。它已经基于“ oracle sql”找到了第一个字符的匹配项,因此您不能仅在oracle上获得匹配项。您找不到每一个。

但是,您可以使用递归函数尝试将相同的字符串与所有项目匹配-已经匹配的项目。

我不确定此代码的性能如何,因为您可以执行很多正则表达式搜索。

import re

def find_all_matches(text, items):
  regex_items = '|'.join(items)
  regex = "(?=({}))".format(regex_items)
  matches = re.findall(regex, text, re.I)
  new_items = [i for i in items if i not in matches]
  if new_items:
    new_matches = find_all_matches(text, new_items)
    return matches + new_matches
  return matches
print find_all_matches("oracle sql", ['oracle sql', 'oracle', 'sql'])

输出:

['oracle sql', 'sql', 'oracle']

没有正则表达式

最后,您可以在不使用正则表达式的情况下实现此功能。再次,我没有看这个的表现。

def find_all_matches(text, items):
  return [i for i in items if i in text]

print find_all_matches("oracle sql", ['oracle sql', 'oracle', 'sql'])

输出:

['oracle sql', 'oracle', 'sql']