4

我有这个预定义的字符串列表,我想在一个大文本文件中进行匹配。问题是文本中确实存在许多这些字符串,但被我想保留的虚假字符/html-xml 标签打断。

例如,我想匹配“联合国总部”,它可以以下列形式存在于文本中:

United Nations & Headquarters
United <br> Nations Headquarters
United Natio<b>ns Hea</b>dquarters

我基本上需要知道这些字符串的位置,后面会处理这些伪字符。我会为不间断的字符串做的是:

sting_locations=[v.span() for v in re.finditer(our_string,text)]

是否可以设置一些正则表达式以某种方式忽略这些中断,或者解决方案是什么?

4

2 回答 2

2
import re

text = """United Nations & Headquarters
United <br> Nations Headquarters
United Natio<b>ns Hea</b>dquarters"""

s = "United Nations Headquarters"

r = re.compile(".*?".join(s))
print([v.span() for v in r.finditer(text)])

关键是".*?".join(s),它.*?在每对连续字符之间插入s以将其转换为正则表达式。

.*?如果您想限制允许的中断,您可能更愿意收紧一点。

于 2013-01-21T20:46:26.117 回答
1

有几个解决方案可以避免灾难性的回溯允许任何数量的中断!


解决方案 A

这是最干净的解决方案,但需要正则表达式模块(在此处获取二进制文件)。它使用原子分组 ,(?>...)来避免回溯:

import regex

strExampleFile = '''United Nations & Headquarters
United <br> Nations Headquarters
United Natio<b>ns Hea</b>dquarters'''

strSearch = 'United Nations Headquarters'

strRegex = regex.sub(r'((?<!^).)',r'(?>[\s\S]*?(?=\1))\1',strSearch)
rexRegex = regex.compile(strRegex)

print([objMatch.span() for objMatch in rexRegex.finditer(strExampleFile)])


解决方案 B

如果您既没有安装也不想安装regex模块,可以使用re来模拟原子分组。但是,搜索字符串现在限制为最多 100 个字符:

import re

strExampleFile = '''United Nations & Headquarters
United <br> Nations Headquarters
United Natio<b>ns Hea</b>dquarters'''

strSearch = 'United Nations Headquarters'

strRegex = re.sub(r'((?<!^).)',r'(?=([\s\S]*?(?=\1)))\\##\1',strSearch)

for numBackReference in range(1,len(strSearch)) :
    strRegex = strRegex.replace("##", str(numBackReference),1)

rexRegex = re.compile(strRegex)

print([objMatch.span() for objMatch in rexRegex.finditer(strExampleFile)])

注意:正如 femtoRgon 所指出的,这两种方法都可能返回误报。

于 2013-01-23T17:14:53.743 回答