正则表达式重叠包含

时间:2019-01-01 20:37:38

标签: python regex regex-lookarounds regex-group

假设我想在字符串中搜索一堆标签,其中一些标签可以是其他标签的子字符串。例如,我想在“他去年参加了加州大学伯克利分校”的文本中搜索标签[“ UC”,“ UC Berkeley”,“ Berkeley”]。我希望所有三个标签都显示出来。但是,当我在Python中运行此代码时,只会得到“ UC”和“ Berkeley”:

import re
string = "He attended UC Berkeley last year."
compiled_regexp = re.compile("UC|UC Berkeley|Berkeley", re.IGNORECASE)

re.findall(compiled_regexp, string)
# result is: ['UC', 'Berkeley']

如何显示所有三个标签?


我的实际用例涉及成千上万个标签,其中许多是其他标签的前缀。也有一些标记是其他标记的前缀,而这些标记本身就是其他标记的前缀,依此类推(例如[“ UC”,“ UCB”,“ UCBA” ...]),为所有对象手动创建捕获组是不可行的其他标签的前缀。有更好的方法吗?


更新
我决定执行以下操作:
首先,我找到所有标记都是其他标记的前缀。然后,我构建了两个单独的正则表达式,一个用于前缀标记,另一个用于非前缀标记。最后,我用两个正则表达式搜索字符串,并将结果组合在一起。

2 个答案:

答案 0 :(得分:0)

re.findall()不支持重叠匹配,并且'UC'与'UC Berkley'的重叠以及'Berkley与'UC Berkley'的重叠。

答案 1 :(得分:0)

少量目标字符串的解决方案

如果只有几个目标字符串,那么手动构建正则表达式模式并执行如下搜索仍然可行:

import re
string = "He attended UC Berkeley last year."
compiled_regexp = re.compile(r"((UC) (Berkeley)|UC|Berkeley)", re.IGNORECASE)

matches = re.findall(compiled_regexp, string)
print(matches)

给出输出:

[('UC Berkeley', 'UC', 'Berkeley')]

有关此正则表达式模式的更多说明,请参见regex101

一般解决方案

我不知道使用正则表达式来搜索大量重叠的相同起始位置目标字符串(看来regex just isn't really designed for this scenario)的任何简便方法。但是,只要您的目标字符串是固定的,列表理解就可以完成这项工作:

string = "He attended UC Berkeley last year."
targets = ["UC Berkeley", "UC", "Berkeley"]
string_lower = string.lower()
found = [target for target in targets if target.lower() in string_lower]
print(found)

给出输出:

['UC Berkeley', 'UC', 'Berkeley']