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()
方法。这基本上包括重复查找两个字符串之间的最长匹配项,然后每次用垃圾字符替换匹配的最长字符串。这也很好用。
我正在尝试使用 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()
方法。这基本上包括重复查找两个字符串之间的最长匹配项,然后每次用垃圾字符替换匹配的最长字符串。这也很好用。