友情鏈接添加在網(wǎng)站中有什么用友情鏈接交換平臺有哪些
diff庫介紹
diff
庫是基于 Myers 差分算法 實現(xiàn)的 JavaScript 文本差異庫。
Myers 差分算法 是由 Eugene Myers 在 1986 年發(fā)表的一篇經(jīng)典算法論文 “An O(ND) Difference Algorithm and its Variations” 中描述的一種高效算法,用于計算兩個序列(通常是字符串)之間的差異。
該算法的時間復雜度為 O(ND),其中:
- N 是兩個序列中較短序列的長度。
- D 是兩個序列之間的最小編輯距離,即從一個序列變換為另一個序列所需的最少操作次數(shù)(插入、刪除或替換)。
通過該算法,diff
庫可以高效地分析文本之間的差異,廣泛應用于文本比對、版本管理和實時內容編輯等場景。
在線演示文檔
diff
庫提供了一個在線演示網(wǎng)站,方便用戶了解其功能:https://kpdecker.github.io/jsdiff
基于在線演示網(wǎng)站,我們可以看到diff
庫支持字符級,詞級, 行級,unified diff
等等的差異比較。
前面三個都好理解,unified diff
則可能需要了解下相應概念。
Unified Diff 和 Patch 的概念
Unified Diff
Unified Diff 是一種標準化的差異格式,用于描述兩個文本文件之間的變化,廣泛使用于版本控制系統(tǒng)(如 Git)。它通過行號和上下文信息展示新增、刪除或修改的內容,是 diff 工具生成的輸出格式之一。
一個 Unified Diff 的典型結構如下:
--- oldFile.txt
+++ newFile.txt
@@ -1,4 +1,4 @@Line 1
-Line 2
+Line 2 updatedLine 3Line 4
解釋:
--- oldFile.txt 和 +++ newFile.txt:分別表示舊文件和新文件的文件名。
@@ -1,4 +1,4 @@:上下文范圍的描述。
-1,4 表示舊文件從第 1 行開始的 4 行。
+1,4 表示新文件從第 1 行開始的 4 行。
- 表示從舊文件中移除的內容。
+ 表示添加到新文件中的內容。
Patch
Patch 是應用這些差異的一種工具,通常配合 Unified Diff 使用。patch 工具可以讀取 Unified Diff 格式的文件,并將其應用到目標文件上,以實現(xiàn)對文件的更新。
diff 庫中的 createPatch 方法生成的就是一個 Unified Diff 格式的輸出??梢杂眠@個輸出作為輸入,再使用 applyPatch 方法將這些差異應用到目標文本中。
diff庫比對的基本流程
diff
庫的所有diff
函數(shù)都用于比較兩個文本,并執(zhí)行以下三個步驟:
1. 將文本分割為 “tokens”
- Token 的定義:Token 是文本中的最小單位,其定義根據(jù)所使用的 diff 方法而變化:
- 在
diffChars
方法中,每個字符是一個token。 - 在
diffWords
方法中,每個單詞是一個token。 - 在
diffLines
方法中,每一行是一個token。
- 在
通過這種分割方式,diff
庫能夠靈活地比較文本的不同層次(如字符、單詞或行)。
2. 找到最小的操作集合
- 目標:通過最少的插入和刪除操作,將第一個 token 數(shù)組轉換為第二個 token 數(shù)組。
- 相等的定義:
- 默認情況下,兩個 token 是否相等由
===
運算符決定。 - 某些 diff 方法支持自定義“相等”定義。例如:
- 默認比較中,
diffChars("Foo", "FOOD")
會認為o
和O
不相等:- 結果:刪除兩個
o
,插入兩個O
和一個D
。
- 結果:刪除兩個
- 設置選項
{ ignoreCase: true }
后,o
和O
會被視為相等:- 結果:僅需要插入一個
D
。
- 結果:僅需要插入一個
- 默認比較中,
- 默認情況下,兩個 token 是否相等由
3. 返回變換結果
- 返回值:一個數(shù)組,表示從舊文本到新文本的轉換過程。
- 數(shù)組結構:包含一系列 change objects。
- 順序:從輸入的起始位置到結束位置按順序排列。
- change objects 的含義:
- 插入:在新文本中添加一個或多個 token(
added: true
)。 - 刪除:從舊文本中刪除一個或多個 token(
removed: true
)。 - 保留:保持一個或多個 token 不變(無
added
或removed
標記)。
- 插入:在新文本中添加一個或多個 token(
示例代碼
以下是 diffChars
的一個簡單示例:
import { diffChars } from 'diff';const oldText = "Foo";
const newText = "FOOD";// 默認比較(區(qū)分大小寫)
const result = diffChars(oldText, newText);
console.log(result);
/* 數(shù)據(jù)格式
[{ value: 'F', count: 1 },{ removed: true, value: 'o' },{ removed: true, value: 'o' },{ added: true, value: 'O' },{ added: true, value: 'O' },{ added: true, value: 'D' }
]
*/// 忽略大小寫
const resultIgnoreCase = diffChars(oldText, newText, { ignoreCase: true });
console.log(resultIgnoreCase);
/* 數(shù)據(jù)格式
[{ value: 'Foo', count: 3 },{ added: true, value: 'D' }
]
*/
diff 庫安裝與使用
1. 安裝庫
通過 npm 安裝:
npm install --save diff
2. 在項目中導入
在 Vue 項目中,可以通過以下方式引入庫中所需的功能:
import { diffWords } from 'diff';
3. 在 Vue 項目中使用
在 Vue 項目中,可以將比對函數(shù)與 v-html
指令結合,動態(tài)渲染高亮比對的結果。
組件模板
<template><div v-html="getYellowDiffText(tableName1, tableName2)"></div>
</template>
組件邏輯
<script>
import { diffWords } from 'diff';export default {data() {return {tableName1: 'Hello world!',tableName2: 'Hello my friend!',};},methods: {/** 比較兩個字符串,標記差異部分為黃色,diff庫比對結果狀態(tài)只有added和removed,新增部分即存在差異部分 */getYellowDiffText(tableName1, tableName2) {let htmltext = '';let diffs = [];if (!tableName2) {diffs = [{ value: tableName1 }];} else {diffs = diffWords(tableName1, tableName2);}diffs.forEach((item) => {htmltext += item.added? `<span style="background-color: yellow;">${item.value}</span>`: item.removed? '' // 個人項目需求不需要比對刪除情況,有需求的可以自行處理: item.value;});return htmltext;},},
};
</script>
diff
庫配置
- 可配置忽略空白字符、大小寫等比較選項。