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

Python's Sequence Matcher gives incomplete match

我正在尝试使用 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])

docs 指出:

get_matching_blocks()

Return list of triples describing matching subsequences. Each triple is of the form (i, j, n), and means that a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in i and j.

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

这可能会做你想做的事 - 虽然不会找到重叠的匹配项(修改为包括子字符串的 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')]

感谢所有回答我 post 的编码员。

作为解决方案,我进行了试验并找到了另一个使用

的解决方案
SequenceMatcher's find_longest_match() 

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