有没有一种方法可以使用levenstein距离将一个特定字符串与第二个较长字符串中的任何区域匹配?
示例:
str1='aaaaa'
str2='bbbbbbaabaabbbb'
if str1 in str2 with a distance < 2:
return True
因此,在上面的示例中,字符串2的部分是aabaa
和distance(str1,str2) < 2
,因此该语句应返回True
。
我能想到的唯一方法就是一次从str2中取5个字符,然后将它与str1进行比较,然后通过str2重复此操作。不幸的是,这似乎效率很低,我需要以这种方式处理大量数据。
答案 0 :(得分:4)
您可以查看支持模糊匹配的regex module:
>>> import regex
>>> regex.search("(aaaaa){s<2}", 'bbbbbbaabaabbbb')
<regex.Match object; span=(6, 11), match='aabaa', fuzzy_counts=(1, 0, 0)>
由于你正在寻找长度相等的字符串,你也可以做一个Hamming distance,它可能比同一两个字符串上的Levenstein距离快得多:
str1='aaaaa'
str2='bbbbbbaabaabbbb'
for s in [str2[i:i+len(str1)] for i in range(0,len(str2)-len(str1)+1)]:
if sum(a!=b for a,b in zip(str1,s))<2:
print s # prints 'aabaa'
答案 1 :(得分:2)
诀窍是生成适当长度b
的所有子串,然后比较每个子串。
def lev_dist(a,b):
length_cost = abs(len(a) - len(b))
diff_cost = sum(1 for (aa, bb) in zip(a,b) if aa != bb)
return diff_cost + length_cost
def all_substr_of_length(n, s):
if n > len(s):
return [s]
else:
return [s[i:i+n] for i in range(0, len(s)-n+1)]
def lev_substr(a, b):
"""Gives minimum lev distance of all substrings of b and
the single string a.
"""
return min(lev_dist(a, bb) for bb in all_substr_of_length(len(a), b))
if lev_substr(str1, str2) < 2:
# it works!
答案 2 :(得分:0)
诀窍通常是使用插入(更短)或删除(更长)成本。您可能还想考虑使用Damerau-Levenshtein。 https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance