文本差異對比工具 go-diff
簡介
純文本差異對比在許多場景下都有應用,如語音識別技術對識別率的評估,需要將識別後的文本與預期文本之間做差異對比計算;又如我們使用 Git 進行代碼提交時,通常會使用git diff
來查看這次編輯發生了哪些改動。
這裏我們先簡單定義一下差異 diff:是指目標文本和源文本之間的區別,也就是將源文本變成目標文本所需要的操作。
以上問題的一個通常解決方案是 Eugene W.Myers 在 1986 年發表的一篇論文 An O(ND) Difference Algorithm and Its Variations 中提出的 Myers 差分算法,該算法是一個能在大部分情況產生「最短的直觀的 diff」的算法。
google/diff-match-patch 項目是 Myers 差分算法的一種實現。但是該項目缺少 Golang 語言的實現。
go-diff 則是 google/diff-match-patch 的一個 Golang 版本的補充。
go-diff 主要提供三個功能:
go-diff 不僅能夠簡潔地輸出字符串對比結果,還能夠輸出規範化的數據結構方便我們的二次開發。
如何使用
go-diff 使用方式非常簡單,代碼如下
const (
text1 = "gocn vip"
text2 = "goCN cool"
)
func main() {
dmp := diffmatchpatch.New()
diffs := dmp.DiffMain(text1, text2, false)
fmt.Println(diffs)
}
執行以上代碼,輸出
[{Equal go} {Insert CN } {Equal c} {Delete n vip} {Insert ool}]
以上輸出結果表示從 text1 變成 text2 需要執行的步驟:
-
go
不需要變動 -
插入
CN
-
c
不需要變動 -
刪除
n vip
-
插入語
ool
DiffMain
方法會查找兩段文本的不同,並以數組形式返回 diff 差異。
這裏的 diff 差異就是從左邊 text1 的字符串變成右邊 text2 的字符串所需要的最少的步驟,每個步驟只能做 “保持不變”、“插入” 或者 “刪除” 操作。如果我們需要的是替換操作,那麼只能是先 “刪除” 後“插入”
工具提供了DiffPrettyText
和DiffPrettyHtml
等方法,可以將 diff 數組轉換成更友好的有顏色高亮的文本或 HTML 格式報告。
DiffTimeout
參數用以設置 diff 計算的超時時間,如果超過此時間,則該計算將被截斷,並返回目前爲止的最佳解決方案。此時儘管結果是正確的,但可能並不是最佳方案。該值爲 0 時可進行無限時的計算。
總結
go-diff 庫實現了高效、完備的文本差異對比算法,在類似需求時,如計算編輯距離、模糊匹配時,不需要我們再去手寫複雜的算法,非常省心和方便。
Reference
git 生成 diff 原理:Myers 差分算法 | 大藝術家_SN (chenshinan.github.io)
Git 是怎樣生成 diff 的:Myers 算法 - CJ Ting's Blog
還想了解更多嗎?
更多請查看:https://github.com/sergi/go-diff
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/qPtt6zZrwDBW7ZVrBC0m3Q