bigString = "AGAHKGHKHASNHADKRGHFKXXX_I_AM_THERE_XXXXXMHHGRFSAHGSKHASGKHGKHSKGHAK"
smallString = "I_AM_HERE"
我应该使用哪种有效算法来查找" bigString"的子字符串。与" smallString"
紧密匹配output = "I_AM_THERE"
与小字符串相比,输出可能没有多少插入和删除。
编辑: 找到了一个很好的例子,非常接近我的问题:How to add variable error to regex fuzzy search. Python
答案 0 :(得分:6)
您可以将almost-ready-to-be-everyones-regex包与模糊匹配结合使用:
>>> import regex
>>> bigString = "AGAHKGHKHASNHADKRGHFKXXX_I_AM_THERE_XXXXXMHHGRFSAHGSKHASGKHGKHSKGHAK"
>>> regex.search('(?:I_AM_HERE){e<=1}',bigString).group(0)
'I_AM_THERE'
或者:
>>> bigString = "AGAH_I_AM_HERE_RGHFKXXX_I_AM_THERE_XXX_I_AM_NOWHERE_EREXXMHHGRFS"
>>> print(regex.findall('I_AM_(?:HERE){e<=3}',bigString))
['I_AM_HERE', 'I_AM_THERE', 'I_AM_NOWHERE']
新的正则表达式模块将(hopefully)成为Python3.4的一部分
如果你有pip,只需输入pip install regex
或pip3 install regex
,直到Python 3.4出来(正则表达式部分...)
回答评论Is there a way to know the best out of the three in your second example? How to use BESTMATCH flag here?
使用最佳匹配标志(?b)
来获得单个最佳匹配:
print(regex.search(r'(?b)I_AM_(?:ERE){e<=3}', bigString).group(0))
# I_AM_THE
或者与difflib结合或使用levenshtein距离以及所有可接受的匹配列表到第一个文字:
import regex
def levenshtein(s1,s2):
if len(s1) > len(s2):
s1,s2 = s2,s1
distances = range(len(s1) + 1)
for index2,char2 in enumerate(s2):
newDistances = [index2+1]
for index1,char1 in enumerate(s1):
if char1 == char2:
newDistances.append(distances[index1])
else:
newDistances.append(1 + min((distances[index1],
distances[index1+1],
newDistances[-1])))
distances = newDistances
return distances[-1]
bigString = "AGAH_I_AM_NOWHERE_HERE_RGHFKXXX_I_AM_THERE_XXX_I_AM_HERE_EREXXMHHGRFS"
cl=[(levenshtein(s,'I_AM_HERE'),s) for s in regex.findall('I_AM_(?:HERE){e<=3}',bigString)]
print(cl)
print([t[1] for t in sorted(cl, key=lambda t: t[0])])
print(regex.search(r'(?e)I_AM_(?:ERE){e<=3}', bigString).group(0))
打印:
[(3, 'I_AM_NOWHERE'), (1, 'I_AM_THERE'), (0, 'I_AM_HERE')]
['I_AM_HERE', 'I_AM_THERE', 'I_AM_NOWHERE']
答案 1 :(得分:0)
使用difflib
:
from difflib import *
window = len(smallString) + 1 # allow for longer matches
chunks = [bigString[i:i+window] for i in range(len(bigString)-window)]
get_close_matches(smallString,chunks,1)
输出:
['_I_AM_THERE']
答案 2 :(得分:0)
也许动态编程问题Longest Common Substring在这里会有一些用处。根据您的需要和匹配标准,您可以使用最长公共子区域