我有一个预定义的字符串列表,我希望在一个大文本文件中匹配。问题是文本中存在许多这些字符串,但是被我想要保留的虚假字符/ 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)]
正则表达式可以设置一些设置来忽略这些中断或解决方案是什么?
答案 0 :(得分: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
,以将其转换为正则表达式。
如果您想限制允许的中断,您可能更愿意将.*?
稍微收紧一点。
答案 1 :(得分:1)
有两个避免灾难性回溯的解决方案和允许任意数量的中断!
解决方案A
这是最干净的解决方案,但需要regex模块(win binaries here)。它使用原子分组(?>...)
来避免回溯:
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模块,则可以使用 来模仿原子分组。但是,搜索字符串现在限制为最多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所指出的,这两种方法都可以返回误报。