代码之家  ›  专栏  ›  技术社区  ›  Blixt

使用SequenceMatcher(python)生成内容差异

  •  2
  • Blixt  · 技术社区  · 14 年前

    我想在Python中生成文本修订版(更具体地说,标记格式的文章)之间的差异。

    我想用类似于 Github 做。

    我看过 difflib 并且发现它做了我想要的。然而, Differ 类的级别太高;我必须分析diff行以生成具有内联diff的HTML。这个 不同 类使用 SequenceMatcher 类以生成其diff。但是看看 序列分析器 相比之下,这是非常低的水平。我甚至还不知道如何进行逐行比较(我承认我没有花很多时间进行试验)。

    有人知道使用 序列分析器 类(除此之外) the difflib documentation )?

    1 回复  |  直到 14 年前
        1
  •  8
  •   LukáÅ¡ Lalinský    14 年前

    SequenceMatcher实际上不是那么低级。最有趣的方法是 get_grouped_opcodes . 它将返回一个生成器,该生成器生成带有更改描述的列表。

    我将用一个例子来解释 random commit on GitHub . 假设你跑了 SequenceMatcher(None, a, b).get_grouped_opcodes() 在旧文件和新文件“tabs_events.js”上。生成器将生成两个组,由GitHub中的“…”行表示。基本上是一组变化。在每个组中,都有存储为元组的详细更改列表。对于第一个组,它返回两个如下所示的更改(第一个项是更改类型,接下来的两个数字表示要删除的行范围,后跟要添加的行范围):

    ('replace', 24, 29, 24, 29)
    ('insert', 33, 33, 33, 35)
    

    第一个命令告诉您将旧文件中的第24-28行(从0开始)替换为新文件中的第24-28行。第二个命令告诉您在旧文件的第33行插入新文件的第33-34行。我想很清楚 'delete' 做和 'equal' 是指在GitHub中未突出显示的行。

    如果您不介意阅读源代码,请查看 difflib.unified_diff() . 它非常简单,生成的纯文本相当于您想要的。