Python的序列匹配器给出了不完全匹配

时间:2016-12-19 04:06:59

标签: python sequence matching

我正在尝试使用Python SequenceMatcher在两个字符串之间找到匹配的块。字符串为"ABCDPQRUVWXYZ""PQRABCDUVWXYZ"。但是,当我应用get_matching_blocks()时,找不到字符串"PQR"作为匹配块。

from difflib import SequenceMatcher

str1 = "ABCDPQRUVWXYZ"
str2 = "PQRABCDUVWXYZ"

matchAll = SequenceMatcher(None, str1, str2, False).get_matching_blocks()

for i in range(0, len(matchAll)):
    print(str1[matchAll[i].a: matchAll[i].a + matchAll[i].size])

3 个答案:

答案 0 :(得分:1)

docs表示:

  

<强> get_matching_blocks()

     

返回描述匹配子序列的三元组列表。每个三元组的形式为(i,j,n),并且意味着a [i:i + n] == b [j:j + n]。   三元组在i和j中单调递增。

如果函数在您的示例中返回"PQR",则j不会单调增加,因为它会从"A"匹配的"ABCD"索引开始,返回"P"匹配的"PQR"索引。

答案 1 :(得分:0)

这可能会做你想要的 - 虽然不会找到重叠的匹配(修改为包含子串的s1和s2中的字符串位置):

str1 = "ABCDEPQRUVWXYZ" # added extra non-matching character
str2 = "PQRABCDUVWXYZ"

def find_subs(s1, s2):
    subs = []
    loc = 0
    while s1:
        s1_copy = s1
        while s1_copy:
            while s1_copy and s1_copy not in s2:
                s1_copy = s1_copy[:-1]
            if s1_copy:
                subs.append((loc, s2.index(s1_copy), s1_copy))
                loc += len(s1_copy)
                s1 = s1[len(s1_copy):]
            else:
                s1 = s1[1:]
                loc += 1
            s1_copy = s1                
    return subs

print(find_subs(str1, str2))

打印:

[(0, 3, 'ABCD'), (5, 0, 'PQR'), (8, 7, 'UVWXYZ')]

答案 2 :(得分:0)

感谢所有回复我帖子的程序员。

作为解决方案,我使用

进行了实验并找到了另一种解决方案
SequenceMatcher's find_longest_match() 

方法。这包括基本上重复找到两个字符串之间的最长匹配,然后每次用垃圾字符替换匹配的最长字符串。这也很有效。