我想使用difflib.SequenceMatcher
从两个字符串中提取最长的公共子字符串。我不确定是发现错误还是误解了find_longest_match
的文档。这一点令我感到困惑:
换句话说,在所有最大匹配块中,返回一个以 最早出现在以及所有开始的最大匹配块中 最早在a中返回最早在b中开始的那个。
(https://docs.python.org/3.5/library/difflib.html#difflib.SequenceMatcher.find_longest_match)
比较字符串X this is a test
和this is a test X
,子字符串X
实际上是一个 maximum 块:它不能扩展(即,它是包含最大值)。此外,它是文本A中的第一个此类最大块。但是,它肯定不是最长的公共子字符串。我强烈怀疑这不是find_longest_match
应该找到的东西。
实际上,在此示例中,find_longest_match
确实找到了最长的公共子字符串:
>>> l = len("X this is a test")
>>> matcher = difflib.SequenceMatcher(None, "X this is a test", "this is a test X")
>>> matcher.find_longest_match(0, l, 0, l)
Match(a=2, b=0, size=14)
但是,就像其他字符串一样,我可以激起上述“查找第一个最大块”(抱歉,长字符串,如果我将其缩短,示例可能会中断):
>>> s1 = "e-like graph visualization using a spanning tree-driven layout technique with constraints specified by layers and the ordering of groups of nodes within layers. We propose a new method of how the orde"
>>> s2 = "itree graph visualization using a spanning tree-driven layout technique with constraints speci ed by layers and the ordering of groups of nodes within layers. We propose a new method of how the drivin"
>>> matcher = difflib.SequenceMatcher(None, s1, s2)
>>> matcher.find_longest_match(1, 149, 5, 149)
Match(a=1, b=47, size=1)
在这种情况下,它将-
中的第一个s1[1]
与-
中的s2[47]
进行匹配。最长的公共子字符串可能是以graph visualization using…
我是否找到错误,或者描述这种行为的文档是否还有另一种解释?
我正在Ubuntu上使用Python 3.5.2。
答案 0 :(得分:3)
好的,我知道了。如果有人遇到相同的问题:SequenceMatcher
的参数autojunk
会产生奇怪的结果:
启发式计算每个单独项目出现在多少次 序列。如果某项重复项(在第一个之后) 超过序列的1%,且序列至少为200 物品长,此物品被标记为“受欢迎”并被视为垃圾物品 出于序列匹配的目的。
据我所知,匹配器永远不会找到包含“垃圾”的任何匹配项。不确定为什么有用,但是默认情况下启用了它。这也解释了为什么当我将字符串缩短时,上面的示例会中断。但是,它确实大大加快了LCS搜索的速度。
因此,结论是:您可能想在构造函数中传递autojunk=False
。