名詞釋義 06:什么是逐字比對 / 字符級比對(Character-level Diff)?

0 評論 735 瀏覽 0 收藏 33 分鐘

逐字比對,文本差異檢測的基石,卻也充滿挑戰(zhàn)。本文深入剖析其技術(shù)原理、應(yīng)用場景及行業(yè)現(xiàn)狀,帶你領(lǐng)略逐字比對的魅力與困境。

從01到05,我們把文檔比對的”上層建筑”基本搭完了:比對是什么、版本是什么、版本控制是什么、差異報告是什么、變更記錄是什么……這些概念回答的都是”做什么”和”為什么做”的問題。

從這一篇開始,我們要往下鉆一層,進(jìn)入”怎么做”的技術(shù)細(xì)節(jié)。

第一個要講的技術(shù)概念,就是:逐字比對 / 字符級比對(Character-level Diff)。

這是所有比對技術(shù)中最基礎(chǔ)、最精細(xì)、也最”笨”的一種。但正是這種”笨功夫”,構(gòu)成了整個比對體系的地基。

一、差之毫厘,謬以千里

《禮記·經(jīng)解》里有句話:「差若毫厘,謬以千里。」

這句話用來形容逐字比對的價值,再合適不過。

大家都知道,彥祖我是一家合同管理系統(tǒng)軟件公司的產(chǎn)品經(jīng)理。在我們這個行業(yè),有兩類文本是”差一個字都不行”的:一類是代碼,一類是合同。

  1. 代碼里少一個分號,程序崩潰;多一個空格,可能編譯不過;把==寫成=,邏輯就全錯了。
  2. 合同里少一個”不”字,意思完全相反;把”5%“寫成”50%”,賠償金額差十倍;把”甲方”寫成”乙方”,責(zé)任主體就換人了。

這兩類文本有一個共同特點(diǎn):每一個字符都有意義,每一個字符的變化都可能帶來巨大的后果。

所以,當(dāng)我們需要比對這類文本時,不能只看”大概改了哪里”,而是要精確到每一個字符——這就是逐字比對存在的意義。

1.1 什么是逐字比對?

用一句話定義:

逐字比對(Character-level Diff)是一種以單個字符為最小比對單位的文本差異檢測技術(shù),它能夠精確識別兩段文本之間每一個字符的新增、刪除和修改。

如果把文檔比對比作”找不同”游戲,那么:

  • 段落比對是”這兩幅畫里,哪個區(qū)域不一樣”——粒度最粗,只告訴你大概位置。
  • 逐行比對是”這兩幅畫里,哪一行不一樣”——粒度中等,能定位到具體的行。
  • 逐字比對是”這兩幅畫里,哪一個像素不一樣”——粒度最細(xì),精確到最小單位。

在文本的世界里,”像素”就是字符。逐字比對就是把兩段文本拆成一個個字符,然后逐一對比,找出所有不同的地方。

1.2 一個簡單的例子

假設(shè)我們有兩個版本的合同條款:

  • 舊版:「乙方應(yīng)在收到貨物后30日內(nèi)完成付款?!?/li>
  • 新版:「乙方應(yīng)在收到貨物后45日內(nèi)完成付款?!?/li>

逐字比對會這樣分析:

  • 「乙」=「乙」?
  • 「方」=「方」?
  • 「應(yīng)」=「應(yīng)」?
  • 「在」=「在」?
  • 「收」=「收」?
  • 「到」=「到」?
  • 「貨」=「貨」?
  • 「物」=「物」?
  • 「后」=「后」?
  • 「3」≠「4」? → 修改
  • 「0」≠「5」? → 修改
  • 「日」=「日」?
  • 「內(nèi)」=「內(nèi)」?

……

最終結(jié)果:發(fā)現(xiàn)2處字符級差異,位置在第10-11個字符,「30」被修改為「45」。

這就是逐字比對的工作方式:不放過任何一個字符的變化。

二、程序員的老朋友:diff命令的前世今生

對于程序員來說,逐字比對不是什么新鮮概念——他們每天都在用,只是可能沒意識到。

2.1 Unix diff:一切的起點(diǎn)

1974年,貝爾實(shí)驗(yàn)室的Douglas McIlroy為Unix系統(tǒng)開發(fā)了diff命令。這個命令的作用很簡單:比較兩個文件,輸出它們的差異。

diff命令的輸出格式后來成為了行業(yè)標(biāo)準(zhǔn),被稱為”diff格式”或”patch格式”。它長這樣:

– old_file.txt

+++ new_file.txt

@@ -1,3 +1,3 @@

第一行內(nèi)容

-舊的第二行

+新的第二行

第三行內(nèi)容

這里的-表示刪除的行,+表示新增的行。

diff命令最初是逐行比對的,但后來的改進(jìn)版本(如GNU diff)增加了–word-diff和字符級比對的能力。

2.2 Git diff:程序員的日常

如果說diff命令是逐字比對的”祖師爺”,那Git diff就是它最成功的”傳人”。

每一個程序員,每天都在用Git diff。當(dāng)你執(zhí)行g(shù)it diff命令時,Git會比較工作區(qū)和暫存區(qū)(或者兩個commit)之間的差異,精確到每一個字符的變化。

Git diff的輸出不僅會告訴你哪一行變了,還會用顏色高亮顯示具體變化的字符:紅色表示刪除,綠色表示新增。

比如你把一個變量名從userName改成username,Git diff會精確地告訴你:刪除了N,這不是整行的變化,而是一個字符的變化。

2.3 代碼審查中的逐字比對

在代碼審查(Code Review)場景中,逐字比對的價值體現(xiàn)得淋漓盡致。

想象一下,一個程序員提交了一個Pull Request,改動了1000行代碼。如果沒有逐字比對,審查者只能看到”這1000行和之前不一樣”,然后一行一行地人工對比。

有了逐字比對,審查者可以清楚地看到:

  • 第123行:把if (a = b)改成了if (a == b)——修復(fù)了一個賦值和比較混淆的Bug。
  • 第456行:把timeout: 30改成了timeout: 300——超時時間從30秒改成了300秒。
  • 第789行:把// TODO: fix this刪掉了——終于把這個TODO處理了。

每一個字符的變化都清清楚楚,審查效率大幅提升。

2.4 IDE中的實(shí)時比對

現(xiàn)代IDE(如VS Code、IntelliJ IDEA、WebStorm)都內(nèi)置了強(qiáng)大的逐字比對功能。

當(dāng)你打開一個文件的歷史版本對比視圖時,IDE會用并排或內(nèi)聯(lián)的方式展示差異,精確到每一個字符。變化的字符會用不同的背景色高亮,讓你一眼就能看出改了什么。

更厲害的是,很多IDE支持”實(shí)時比對”——你一邊編輯,它一邊顯示和上一個保存版本的差異。這對于代碼重構(gòu)特別有用:你可以隨時看到自己改了哪些地方,避免改著改著忘了改過什么。

三、合同系統(tǒng)中的逐字比對:一個字都不能錯

講完了程序員的世界,現(xiàn)在回到合同系統(tǒng)。

在合同管理領(lǐng)域,逐字比對的重要性一點(diǎn)都不比代碼低——甚至更高。因?yàn)榇a錯了,最多是系統(tǒng)崩潰,可以修復(fù);合同錯了,可能是幾百萬的損失,而且簽了就生效,想改都改不了。

3.1 合同中”一字之差”的血淚教訓(xùn)

在合同管理的江湖里,流傳著無數(shù)”一字之差”釀成大禍的故事。

故事一:少了一個”不”字。

某公司的采購合同里有一條:”乙方不得將本合同項(xiàng)下的權(quán)利義務(wù)轉(zhuǎn)讓給第三方。”結(jié)果在某一版修改中,”不”字被誤刪,變成了”乙方得將本合同項(xiàng)下的權(quán)利義務(wù)轉(zhuǎn)讓給第三方。”意思完全相反。等到乙方真的把合同轉(zhuǎn)讓給了一個資質(zhì)很差的第三方,甲方才發(fā)現(xiàn)問題,但為時已晚。

故事二:小數(shù)點(diǎn)點(diǎn)錯位置。

某工程合同的違約金條款寫的是”違約金為合同金額的0.5%“,結(jié)果在打印時小數(shù)點(diǎn)丟失,變成了”違約金為合同金額的5%”。一個1000萬的合同,違約金從5萬變成了50萬,差了整整10倍。

故事三:甲乙方寫反了。

某服務(wù)合同的保密條款寫的是”甲方應(yīng)對乙方提供的技術(shù)資料承擔(dān)保密義務(wù)”,結(jié)果在修改過程中,甲乙方被調(diào)換,變成了”乙方應(yīng)對甲方提供的技術(shù)資料承擔(dān)保密義務(wù)”。保密義務(wù)的承擔(dān)方完全反了。

這些故事的共同點(diǎn)是:如果當(dāng)時有逐字比對,這些錯誤在簽署前就能被發(fā)現(xiàn)。

3.2 合同比對的特殊挑戰(zhàn)

相比代碼比對,合同比對面臨一些特殊的挑戰(zhàn):

第一,格式干擾。代碼通常是純文本,格式簡單;合同通常是Word或PDF,有復(fù)雜的格式(字體、字號、顏色、縮進(jìn)、表格等)。逐字比對需要能夠”穿透”格式,只比較文字內(nèi)容。

第二,中文特性。英文單詞之間有空格分隔,比對時可以以單詞為單位;中文沒有空格,只能以字符為單位。而且中文有很多形近字(如”己”和”已”、“戊”和”戌”),人眼很難發(fā)現(xiàn),必須靠機(jī)器逐字比對。

第三,法律語言的精確性。法律文本對用詞極其講究,“應(yīng)當(dāng)”和”可以”、“或”和”及”、“之前”和”之日前”,這些細(xì)微的差別都有不同的法律含義。逐字比對必須能夠捕捉這些細(xì)微差異。

第四,多版本流轉(zhuǎn)。一份合同從起草到簽署,可能要經(jīng)過十幾個版本,在業(yè)務(wù)、法務(wù)、客戶之間來回修改。每一次修改都可能引入新的差異,逐字比對需要能夠追蹤整個版本鏈條。

3.3 理想很豐滿,現(xiàn)實(shí)很骨感

講到這里,我要給團(tuán)隊(duì)里的年輕同事潑一盆冷水:純粹的逐字比對,在實(shí)際的文檔比對產(chǎn)品中幾乎不存在。

不是技術(shù)上做不到,而是做出來沒法用。

為什么?因?yàn)橹鹱直葘Φ那疤崾?#8221;兩段文本已經(jīng)被準(zhǔn)確提取出來了”。但在真實(shí)的業(yè)務(wù)場景中,文檔往往是Word、PDF、掃描件,甚至是拍照件。要把這些文檔變成可比對的文本,需要經(jīng)過OCR識別、版面分析、文本提取等一系列步驟。

問題就出在這里。

如果用傳統(tǒng)OCR做逐字比對,只要坐標(biāo)差一點(diǎn)點(diǎn),就會被識別為差異。比如同一份合同,掃描時稍微歪了一點(diǎn),或者打印時邊距不一樣,OCR提取出來的文本位置就會有偏差。這時候做逐字比對,會產(chǎn)生大量的”偽差異”——明明內(nèi)容一樣,系統(tǒng)卻說不一樣。

更麻煩的是表格。表格里的文字如果跨行、跨列,OCR的閱讀順序可能會亂掉。本來是”第一行第一列、第一行第二列”,結(jié)果被識別成”第一列第一行、第一列第二行”。這時候做逐字比對,結(jié)果就是一團(tuán)亂麻。

所以,逐字比對是一個“理論上正確”的概念,但在實(shí)際產(chǎn)品中,必須結(jié)合大量的預(yù)處理和后處理,才能真正可用。

四、行業(yè)現(xiàn)狀:從OCR到視覺大模型

既然純粹的逐字比對不好用,那行業(yè)里的玩家們都在怎么做?

這一節(jié),我想給團(tuán)隊(duì)的年輕同事講講行業(yè)現(xiàn)狀,讓大家對自己所處的賽道有個清醒的認(rèn)識。

4.1 傳統(tǒng)方案:OCR + 規(guī)則引擎

早期的文檔比對產(chǎn)品,基本都是這個套路:

第一步,用OCR把文檔轉(zhuǎn)成文本。

第二步,用規(guī)則引擎做文本對齊和比對。

第三步,輸出差異結(jié)果。

這個方案的優(yōu)點(diǎn)是邏輯清晰、可控性強(qiáng)。缺點(diǎn)是對OCR的準(zhǔn)確率要求極高,而且規(guī)則引擎很難覆蓋所有的邊界情況。

在標(biāo)準(zhǔn)化程度高的場景(比如打印清晰的合同、格式統(tǒng)一的表單),這個方案效果還不錯。但一旦遇到掃描件質(zhì)量差、版面復(fù)雜、手寫內(nèi)容等情況,準(zhǔn)確率就會斷崖式下跌。

4.2 新興方案:視覺大模型

最近幾年,隨著深度學(xué)習(xí)和大模型技術(shù)的發(fā)展,越來越多的產(chǎn)品開始采用視覺大模型來做文檔理解和比對。

視覺大模型的思路是:不再把文檔拆成”OCR識別→文本比對”兩個獨(dú)立的步驟,而是讓模型直接”看”文檔圖像,理解其中的內(nèi)容和結(jié)構(gòu)。

這個方案的優(yōu)點(diǎn)是對復(fù)雜版面的適應(yīng)性更強(qiáng),不需要人工編寫大量規(guī)則。缺點(diǎn)也很明顯:

  • 閱讀順序問題。模型可能會把文檔的閱讀順序搞錯,比如把頁眉當(dāng)成正文,把腳注當(dāng)成段落。
  • 聯(lián)想問題。大模型有時候會”腦補(bǔ)”,把文檔里沒有的內(nèi)容聯(lián)想出來,或者把相似的內(nèi)容混淆。
  • 可解釋性差。傳統(tǒng)方案出了問題,可以一步步排查是哪個環(huán)節(jié)出錯;大模型出了問題,往往只能說”模型就是這么判斷的”,很難解釋原因。
  • 計(jì)算成本高。視覺大模型的推理成本比傳統(tǒng)OCR高很多,對于大批量文檔比對場景,成本是個問題。

4.3 行業(yè)玩家的不同選擇

目前市面上做文檔比對的公司,基本都在”傳統(tǒng)方案”和”大模型方案”之間尋找平衡點(diǎn),而且各有側(cè)重:

  • 有的公司專注于法律文書場景,比如法狗狗。法律文書的格式相對規(guī)范,用詞有固定套路,所以可以針對法律領(lǐng)域做深度優(yōu)化。但脫離了法律文書場景,換成其他類型的文檔,效果就會大打折扣。
  • 有的公司專注于金融類文件,比如庖丁科技。金融文件有大量的表格、數(shù)字、專業(yè)術(shù)語,需要針對這些特點(diǎn)做專門的處理。但遇到手寫內(nèi)容或者非標(biāo)準(zhǔn)格式,準(zhǔn)確率也會下降很多。
  • 有的公司專注于合同場景,比如肇新科技。在合同領(lǐng)域做到了很高的準(zhǔn)確率,但換成手寫文檔、外語文檔,準(zhǔn)確率也會從99%以上降到95%左右。

這就是行業(yè)的現(xiàn)狀:沒有一家公司能做到“通吃”,大家都是在自己擅長的領(lǐng)域深耕,犧牲某些場景的能力來強(qiáng)化核心場景的表現(xiàn)。

4.4 關(guān)于準(zhǔn)確率的真相

經(jīng)常有客戶問:“你們的比對準(zhǔn)確率是多少?”

這個問題看似簡單,其實(shí)很難回答。因?yàn)闇?zhǔn)確率是和場景強(qiáng)相關(guān)的。

同一個產(chǎn)品,在標(biāo)準(zhǔn)打印合同上可能做到99.9%的準(zhǔn)確率;換成掃描件,可能降到98%;換成手寫文檔,可能降到95%;換成外語文檔,可能降到90%。

所以,永遠(yuǎn)不要跟客戶說“我們的準(zhǔn)確率是100%”。

100%是不存在的。任何一個誠實(shí)的從業(yè)者都會告訴你,文檔比對是一個”盡可能準(zhǔn)確”而不是”絕對準(zhǔn)確”的事情。

正確的回答方式是:說明在什么場景下、什么條件下,能達(dá)到什么樣的準(zhǔn)確率。比如:“在標(biāo)準(zhǔn)打印的中文合同場景下,我們的比對準(zhǔn)確率可以達(dá)到99%以上;如果是掃描件或者手寫內(nèi)容,準(zhǔn)確率會有所下降,具體取決于文檔質(zhì)量?!?/p>

這才是對客戶負(fù)責(zé)的態(tài)度,也是對自己產(chǎn)品的清醒認(rèn)知。

五、逐字比對的技術(shù)原理

講完了行業(yè)現(xiàn)狀,現(xiàn)在來聊聊技術(shù)原理。逐字比對看起來簡單,背后其實(shí)有不少學(xué)問。

5.1 最長公共子序列(LCS)算法

逐字比對最經(jīng)典的算法是LCS(Longest Common Subsequence,最長公共子序列)算法。

簡單來說,LCS算法的思路是:找到兩個字符串中最長的公共部分,剩下的就是差異。

舉個例子:

  • 字符串A:ABCDEFG
  • 字符串B:ABXDEFG

LCS算法會找到最長公共子序列:ABDEFG(注意,C和X不在公共子序列里)

然后通過比較,得出結(jié)論:A中的C被替換成了B中的X。

LCS算法的時間復(fù)雜度是O(m×n),其中m和n分別是兩個字符串的長度。對于短文本來說,這個復(fù)雜度完全可以接受;但對于長文檔(比如幾十頁的合同),直接用LCS可能會比較慢。

5.2 Myers差異算法

1986年,Eugene W. Myers發(fā)表了一篇論文,提出了一種更高效的差異算法,后來被稱為Myers算法。Git的diff功能就是基于Myers算法實(shí)現(xiàn)的。

Myers算法的核心思想是:把差異比對問題轉(zhuǎn)化為圖論中的最短路徑問題。它能夠在O((m+n)×d)的時間復(fù)雜度內(nèi)完成比對,其中d是兩個字符串之間的差異數(shù)量。當(dāng)差異較小時(這是大多數(shù)實(shí)際場景),Myers算法比LCS快很多。

5.3 字符級 vs 詞級 vs 行級

在實(shí)際應(yīng)用中,逐字比對并不總是最佳選擇。根據(jù)不同的場景,可能需要選擇不同的比對粒度:

  • 字符級比對:精度最高,能發(fā)現(xiàn)任何細(xì)微的變化。適合對精確性要求極高的場景,如合同條款、法律文書、代碼等。缺點(diǎn)是輸出結(jié)果可能過于瑣碎,比如一個單詞改了一個字母,會顯示為”刪除一個字符+新增一個字符”,而不是”修改了一個單詞”。
  • 詞級比對:以單詞為單位進(jìn)行比對。適合英文文本,能夠更好地展示”哪個單詞變了”。但對中文不太適用,因?yàn)橹形臎]有明確的單詞邊界。
  • 行級比對:以行為單位進(jìn)行比對。適合代碼、配置文件等以行為邏輯單位的文本。優(yōu)點(diǎn)是結(jié)果清晰,缺點(diǎn)是粒度較粗,如果一行中只改了一個字符,整行都會被標(biāo)記為”已修改”。

在實(shí)際的合同比對系統(tǒng)中,通常會采用”多層比對”的策略:先做行級比對,找出有差異的行;然后對有差異的行再做字符級比對,精確定位變化的字符。這樣既保證了效率,又保證了精度。

5.4 處理中文的特殊考慮

中文逐字比對有一些特殊的考慮:

  • 編碼問題。中文字符在不同編碼下(UTF-8、GBK、GB2312等)的字節(jié)表示不同。比對前需要統(tǒng)一編碼,否則可能出現(xiàn)亂碼或誤判。
  • 標(biāo)點(diǎn)符號。中文有全角和半角兩套標(biāo)點(diǎn)符號,比如中文逗號「,」和英文逗號「,」。在比對時,需要決定是否把它們視為相同字符。
  • 空白字符。中文文本中可能混雜著全角空格、半角空格、制表符、換行符等各種空白字符。這些空白字符在視覺上可能看不出區(qū)別,但在逐字比對時會被識別為差異。通常需要做預(yù)處理,統(tǒng)一空白字符的表示。
  • 形近字。中文有很多形近字,如”己已巳”、“戊戌戍”、”日曰”等。這些字在視覺上非常相似,人眼很難分辨,但逐字比對可以準(zhǔn)確識別。這也是逐字比對在中文合同場景中特別有價值的原因之一。

六、逐字比對的優(yōu)缺點(diǎn)

任何技術(shù)都有其適用場景和局限性,逐字比對也不例外。

6.1 優(yōu)點(diǎn)

  • 精度高。逐字比對是所有比對技術(shù)中精度最高的,能夠發(fā)現(xiàn)任何字符級別的變化,不會遺漏任何差異。
  • 無歧義。比對結(jié)果是確定性的,同樣的輸入一定得到同樣的輸出。不存在”可能是這樣,也可能是那樣”的模糊情況。
  • 可追溯。每一個差異都有明確的位置信息,可以精確定位到第幾個字符。這對于后續(xù)的審閱和處理非常重要。
  • 技術(shù)成熟。逐字比對的算法已經(jīng)發(fā)展了幾十年,非常成熟穩(wěn)定。各種編程語言都有現(xiàn)成的庫可以使用。

6.2 缺點(diǎn)

  • 結(jié)果可能過于瑣碎。如果兩個版本差異較大,逐字比對的結(jié)果可能會非常長,充滿了”刪除一個字符””新增一個字符”這樣的細(xì)節(jié),讓人看得眼花繚亂。
  • 不理解語義。逐字比對只關(guān)心字符本身,不理解字符的含義。比如把”5%“改成”五percent”,逐字比對會認(rèn)為這是很大的變化(刪除了2個字符,新增了9個字符),但從語義上看,這可能只是格式的調(diào)整,實(shí)際含義沒變。
  • 對格式敏感。如果兩個版本的格式不同(比如一個用全角標(biāo)點(diǎn),一個用半角標(biāo)點(diǎn)),逐字比對會把這些格式差異也識別出來,產(chǎn)生大量”噪音”。
  • 性能問題。對于非常長的文本,逐字比對的計(jì)算量可能很大。雖然有各種優(yōu)化算法,但在極端情況下仍然可能遇到性能瓶頸。

6.3 什么時候用逐字比對?

基于以上優(yōu)缺點(diǎn),逐字比對最適合以下場景:

  • 對精確性要求極高的文本。如合同條款、法律文書、財務(wù)報表、技術(shù)規(guī)格書等。這些文本”差一個字都不行”,必須用最精細(xì)的比對方式。
  • 文本長度適中。幾頁到幾十頁的文檔,逐字比對的性能完全可以接受。如果是幾百頁的長文檔,可能需要結(jié)合其他技術(shù)(如先做段落級比對,再對有差異的段落做逐字比對)。
  • 需要精確定位差異位置。如果后續(xù)需要對差異進(jìn)行逐一審閱、批注、確認(rèn),那么逐字比對提供的精確位置信息就非常有價值。
  • 版本之間差異較小。如果兩個版本差異很大(比如重寫了一半以上的內(nèi)容),逐字比對的結(jié)果可能會很亂,這時候可能需要結(jié)合段落級比對來展示。

七、逐字比對與其他比對技術(shù)的關(guān)系

在前面的規(guī)劃中,我們提到了多種比對技術(shù):逐字比對、逐行比對、段落比對、結(jié)構(gòu)化比對、語義比對等。這些技術(shù)不是互相替代的關(guān)系,而是互相補(bǔ)充的關(guān)系。

7.1 比對技術(shù)的”金字塔”

可以把各種比對技術(shù)想象成一個金字塔:

  1. 最底層是逐字比對(字符級)。這是最基礎(chǔ)、最精細(xì)的比對,所有其他比對技術(shù)最終都要落到字符級別。
  2. 往上一層是逐詞比對(詞級)。以單詞為單位,適合英文文本。
  3. 再往上是逐行比對(行級)。以行為單位,適合代碼和配置文件。
  4. 再往上是段落比對(段落級)。以段落為單位,適合長文檔的快速瀏覽。
  5. 再往上是結(jié)構(gòu)化比對。理解文檔的結(jié)構(gòu)(標(biāo)題、章節(jié)、條款),在結(jié)構(gòu)層面進(jìn)行比對。
  6. 最頂層是語義比對。理解文本的含義,判斷語義是否發(fā)生了變化。

越往上,粒度越粗,但”智能程度”越高;越往下,粒度越細(xì),但更加”機(jī)械”。

7.2 多層比對的實(shí)踐

在實(shí)際的文檔比對系統(tǒng)中,通常不會只用一種比對技術(shù),而是多種技術(shù)結(jié)合使用。

一個典型的流程是:

第一步,結(jié)構(gòu)化比對。先識別文檔的結(jié)構(gòu),把文檔拆分成章節(jié)、條款、段落等邏輯單元。

第二步,段落級比對。在結(jié)構(gòu)對齊的基礎(chǔ)上,比較對應(yīng)段落是否有差異。

第三步,行級比對。對有差異的段落,進(jìn)一步比較每一行。

第四步,字符級比對。對有差異的行,精確到每一個字符。

這種”由粗到細(xì)”的比對策略,既保證了效率(大部分沒有差異的內(nèi)容可以快速跳過),又保證了精度(有差異的地方會被精確定位)。

7.3 逐字比對是”地基”

在這個金字塔中,逐字比對是最底層的”地基”。

無論上層用什么技術(shù),最終展示給用戶的差異,都需要落到字符級別。用戶想知道的不只是”這一段有變化”,而是”這一段的第幾個字變成了什么”。

所以,逐字比對雖然”笨”,但不可或缺。它是整個比對體系的基礎(chǔ)能力。

八、常見誤區(qū)

在實(shí)際工作中,很多人對逐字比對存在一些誤解。

8.1 “逐字比對就是簡單的字符串比較”

這是最常見的誤解。

簡單的字符串比較只能告訴你”兩個字符串是否相等”,不能告訴你”哪里不同、怎么不同”。

逐字比對不只是比較,還要輸出差異的詳細(xì)信息:哪些字符被刪除了、哪些字符被新增了、哪些字符被修改了、每個差異的位置在哪里。

這需要用到專門的差異算法(如LCS、Myers等),比簡單的字符串比較復(fù)雜得多。

8.2 “逐字比對能解決所有比對問題”

逐字比對精度高,但不是萬能的。

  • 對于格式復(fù)雜的文檔(如Word、PDF),需要先做格式解析,才能進(jìn)行逐字比對。
  • 對于掃描件,需要先做OCR識別,才能得到可比對的文本。
  • 對于語義層面的變化(如同義詞替換、句式調(diào)整),逐字比對可能會產(chǎn)生大量”噪音”,需要結(jié)合語義比對技術(shù)。

逐字比對是基礎(chǔ)能力,但不是全部能力。一個完整的文檔比對系統(tǒng),需要多種技術(shù)的配合。

8.3 “逐字比對的結(jié)果就是最終結(jié)果”

逐字比對的原始結(jié)果通常需要進(jìn)一步處理,才能呈現(xiàn)給用戶。

比如:

  • 連續(xù)的字符變化可以合并成一個”修改塊”,而不是顯示為一堆零散的”刪除+新增”。
  • 無意義的格式差異(如空格、換行)可以被過濾掉,只保留有意義的內(nèi)容差異。
  • 關(guān)鍵字段的變化(如金額、日期、主體)可以被特別標(biāo)注,提醒用戶重點(diǎn)關(guān)注。

這些”后處理”工作,是把逐字比對從”技術(shù)能力”變成”用戶體驗(yàn)”的關(guān)鍵。

九、小結(jié):一句話記住”逐字比對”

最后,用一句話來總結(jié):

逐字比對(Character-level Diff)是以單個字符為最小單位的文本差異檢測技術(shù),能夠精確識別兩段文本之間每一個字符的新增、刪除和修改,是所有比對技術(shù)中精度最高的基礎(chǔ)能力。

它的核心價值在于兩個字:精確。

  • 在代碼的世界里,它幫助程序員發(fā)現(xiàn)每一個字符的變化,避免因?yàn)橐粋€分號、一個空格而引發(fā)的Bug。
  • 在合同的世界里,它幫助法務(wù)和業(yè)務(wù)發(fā)現(xiàn)每一個字的變化,避免因?yàn)橐粋€”不”字、一個小數(shù)點(diǎn)而引發(fā)的損失。

逐字比對看起來”笨”,但正是這種”笨功夫”,構(gòu)成了整個比對體系的地基。沒有它,上層的所有”智能”都是空中樓閣。

在接下來的文章里,我們會繼續(xù)介紹其他比對技術(shù):逐行比對、段落比對、結(jié)構(gòu)化比對、語義比對……一步步把這套比對技術(shù)體系搭建完整。

本文由 @合同管理吳彥祖 原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理。未經(jīng)作者許可,禁止轉(zhuǎn)載

題圖來自 Unsplash,基于CC0協(xié)議

該文觀點(diǎn)僅代表作者本人,人人都是產(chǎn)品經(jīng)理平臺僅提供信息存儲空間服務(wù)

更多精彩內(nèi)容,請關(guān)注人人都是產(chǎn)品經(jīng)理微信公眾號或下載App
評論
評論請登錄
  1. 目前還沒評論,等你發(fā)揮!