Python中SequenceMatcher方法的理解和使用

例如现有如下代码:

def extract_matching_text(text1, text2):
    # 使用 difflib 的 SequenceMatcher 来找到相同的部分
    matcher = difflib.SequenceMatcher(None, text1, text2)
    matches = []

    # 获取相同的文本块
    for match in matcher.get_matching_blocks():
        # match.a 是第一个文本的起始位置,match.b 是第二个文本的起始位置,match.size 是匹配的长度
        if match.size > 0:
            matches.append(text1[match.a: match.a + match.size])

    # 合并所有相同的内容
    matching_text = '\n'.join(matches)
    logging.info(f"Matching text between the two documents:\n{matching_text}")

    return matching_text

这个函数 extract_matching_text 的作用是从两个文本 text1text2 中提取出它们之间的相同部分,并返回这些匹配的文本片段。它使用 difflib.SequenceMatcher 来识别两个文本之间的相似或相同部分。

主要步骤解释:

  1. 创建 SequenceMatcher 对象:

matcher = difflib.SequenceMatcher(None, text1, text2)
    • SequenceMatcher 是 Python 标准库 difflib 模块中的一个类,用于比较两个序列(如字符串)之间的相似度。
    • 传递给 SequenceMatcher 的参数:
      • 第一个参数 None:表示不使用自定义的匹配规则(即,默认的比较方式)。
      • text1text2 是要比较的两个字符串。
  • 2.找到相同的文本块:

for match in matcher.get_matching_blocks():
  • matcher.get_matching_blocks() 返回一组匹配的文本块,每个块表示 text1text2 中的相同部分。
  • 每个 match 对象包含三个属性:
    • match.a:第一个文本 text1 中相同部分的起始位置。
    • match.b:第二个文本 text2 中相同部分的起始位置。
    • match.size:匹配的字符长度,即相同的部分有多少字符。

  3.提取相同的文本:

if match.size > 0:
    matches.append(text1[match.a: match.a + match.size])
    • 如果匹配的文本长度 match.size 大于 0,说明确实有相同的部分。
    • text1 中的相同片段提取出来,并将其添加到 matches 列表中。
  • 合并所有相同的内容:

matching_text = '\n'.join(matches)

将所有匹配的文本片段用换行符 \n 连接起来,形成一个包含所有相同部分的字符串。

日志记录:

logging.info(f"Matching text between the two documents:\n{matching_text}")
    • 将匹配到的文本内容记录到日志中(这部分是用于调试或监控)。
  1. 返回值:

    • 返回 matching_text,即 text1text2 中相同的文本部分。

SequenceMatcher 的作用和概念:

SequenceMatcher 是一个用来比较两个序列(如字符串或列表)相似度的工具。它主要用于查找两个序列中的相同片段,或者计算它们之间的相似度。

  • 概念
    • SequenceMatcher 不直接按字面或逐字比较,而是寻找两个序列中最相似的部分。这种比较方式非常适合用于查找文本中的相同或相似段落,即使它们的位置不同。
  • 作用
    • 用于比较两个文本或序列,识别其中的相同部分。
    • 能够处理插入、删除、替换等多种不同的文本变动情况,并找出最长的公共子序列(LCS)。

通俗解释:

你可以把 SequenceMatcher 想象成一个“文本对比工具”,它会从两个文本中找出相同的部分,忽略它们的顺序或其他不匹配的部分。

举例说明:

假设我们有以下两个文本:

text1 = "This is a simple example."
text2 = "This is an example of a simple test."

调用 extract_matching_text(text1, text2) 后,SequenceMatcher 会识别出两个文本中的相同部分:

  • "This is a"
  • "example"
  • "simple"

最终函数会返回这些相同的片段,合并后如下:

This is a
example
simple

这段输出表示两个文本中共同包含的部分。

 

解读下如下代码的返回结果

def compare_texts(text1, text2):
    matcher = SequenceMatcher(None, text1, text2)
    return matcher.get_opcodes()  # 返回数据结构类似:('equal', 0, 16, 0, 16) ('replace', 16, 19, 16, 19), 也就是difference
  1. SequenceMatcher: 这是 Python 标准库 difflib 中的一个类,用来比较两个序列(这里是两个字符串 text1text2)并找到它们的相同或不同部分。

  2. get_opcodes(): 这个方法返回一个列表,其中每个元素都是一个元组,描述了文本之间的变化。每个元组的格式是:(tag, i1, i2, j1, j2),其中:

    • tag: 描述了操作类型,表示 text1text2 在相应片段上的关系。
    • i1, i2: text1 中受影响的索引范围 [i1:i2]
    • j1, j2: text2 中对应的索引范围 [j1:j2]

返回的 tag 类型:

  • equal: 这部分文本在两个字符串中是相同的。
  • replace: 这部分文本在两个字符串中不同,并且被替换。
  • delete: text1 中的这部分文本在 text2 中没有。
  • insert: text2 中的这部分文本在 text1 中没有。

举例:

假设 text1 = "abcdef"text2 = "abcxyzf",执行 compare_texts(text1, text2) 后的返回可能是:

[('equal', 0, 3, 0, 3), ('replace', 3, 6, 3, 6), ('equal', 6, 7, 6, 7)]

解释这个返回值:

  • ('equal', 0, 3, 0, 3): text1[0:3]text2[0:3] 相等,即 "abc".
  • ('replace', 3, 6, 3, 6): text1[3:6]text2[3:6] 被替换,"def" 被替换为 "xyz".
  • ('equal', 6, 7, 6, 7): text1[6:7]text2[6:7] 相等,即 "f".

总结:

compare_texts 函数返回的结果是一个包含多个操作的列表,描述了 text1text2 的差异,帮助你理解两段文本之间哪些部分相同、被替换、删除或插入。

 

posted @ 2024-09-12 09:43  AlphaGeek  阅读(650)  评论(0)    收藏  举报