使用SequenceMatcher生成内容差异(Python)
我想在Python中生成两个文本版本之间的差异(更具体来说,是Markdown格式的文章)。
我希望这个差异的格式能和Github上显示的类似。
我查看了difflib
,发现它能满足我的需求。不过,Differ
这个类太高级了;我需要解析差异行才能生成带有内联差异的HTML。Differ
类使用SequenceMatcher
类来生成差异。但看起来SequenceMatcher
的功能比较底层。我甚至还没弄明白怎么进行逐行比较(我承认我没有花太多时间去尝试)。
有没有人知道使用SequenceMatcher
类的资源(除了difflib的文档)?
1 个回答
SequenceMatcher其实并没有那么复杂。对你来说,最有趣的方法是 get_grouped_opcodes
。这个方法会返回一个生成器,它会生成一些包含更改描述的列表。
我用一个来自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行。第二个更改则告诉你要在旧文件的第33行插入新文件的第33-34行。我想你应该能明白 'delete'
是做什么的,而 'equal'
是那些在GitHub上没有高亮显示的行。
如果你不介意看源代码,可以看看 difflib.unified_diff()
的实现。它其实很简单,可以生成你想要的纯文本格式。