2010-05-04 225 views
2

我想在Python中生成文本(更具體地說,Markdown格式的文章)的修訂版本之間的差異。使用SequenceMatcher生成內容差異(Python)

我想以與Github相似的方式格式化此差異。我看過difflib,並發現它做我想要的。但是,Differ課程太高級;我將不得不解析差異線以生成帶有內嵌差異的HTML。 Differ類使用SequenceMatcher類來生成其差異。但看看SequenceMatcher這是相當低級別的。我甚至還沒有想出如何做一行一行的差異(我承認我沒有花很多時間試驗)。

有沒有人知道使用SequenceMatcher類的任何資源(除了the difflib documentation)?

回答

7

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行(從0開始)替換新文件中的第24-28行。第二個告訴你從舊文件的第33行的新文件中插入第33-34行。我想很清楚'delete''equal'是那些在GitHub中沒有突出顯示的行。

如果您不介意閱讀源代碼,請查看difflib.unified_diff()的實現。它非常簡單,它生成一個與你想要的相同的純文本。