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

时间:2010-05-04 18:09:18

标签: python diff

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

我想以与Github类似的方式格式化此差异。

我看过difflib并发现它符合我的要求。但是,Differ类太高级了;我将不得不解析diff行来生成带内联差异的HTML。 Differ类使用SequenceMatcher类来生成其差异。但是看一下SequenceMatcher它的水平相当低。我甚至都没想出如何做一个逐行的差异(我承认我没有花很多时间进行实验)。

是否有人知道使用SequenceMatcher课程的任何资源(the difflib documentation除外)?

1 个答案:

答案 0 :(得分:8)

SequenceMatcher实际上并不是那种低级别。最有趣的方法是get_grouped_opcodes。它将返回一个生成器,生成包含更改描述的列表。

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

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

第一个告诉您从旧文件中用新文件中的第24-28行替换第24-28行(从0开始)。第二个告诉您在旧文件的第33行插入新文件中的第33-34行。我认为很明显'delete'会做什么,而'equal'是那些未在GitHub中突出显示的行。

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