在线文本 Diff 工具:逐行对比两段文本的差异
什么是文本 Diff
文本 Diff(Difference)是对比两段文本并标出差异的技术。版本控制系统里的 git diff 是最常见的形态:按行(或更细粒度)给出增删轨迹,而不是「作者真实的点击顺序」。
在线 文本 Diff 适合把两份已经到手的快照贴进浏览器——环境配置、接口响应、日志片段、代码摘录——无需装客户端即可并排或统一视图阅读差异。数据留在本地;要追溯提交历史仍应使用 git log -p。
为什么需要文本 Diff 对比
- 代码片段审查:对比改动前后的函数或补丁草稿,快速圈定变更块
- 配置管理:对比两个环境的 Nginx、
.env、Compose 片段 - 文档与翻译:核对修订稿是否漏段、多段
- 日志分析:两份日志「看起来差不多」时定位真正漂移的行
- 结构化数据前的粗扫:JSON/YAML 在语义 Diff 之前,先用文本 Diff 看序列化噪音
如何使用 ToolVault 文本 Diff
打开 文本 Diff 工具:
- 左侧贴「原始」文本,右侧贴「修改后」文本(标签为 Original / Modified)
- 无需点 Compare:只要任一侧有内容,下方即出现 Diff 视图
- 可选 Ignore whitespace(按行 trim)与 Ignore case(整段转小写后再比)
- 切换 并排(side-by-side) 或 统一(unified) 布局
- 底部统计条显示
+added / -removed / ~modified / =unchanged以及左右行数
颜色语义以 Monaco Diff 为准:新增偏绿、删除偏红。所谓「修改」在多数行级 Diff 里会呈现为「删旧行 + 增新行」;底部的 ~modified 来自另一套按行号对齐的计数(见实现注记),不要把它理解成独立的黄色高亮模式。
可用 Example / Swap / Clear 加载示例、交换两侧或清空。两侧内容会写入浏览器本地持久化键,刷新后仍在——比对含密钥的材料后记得 Clear。
Diff 算法:LCS、Myers、Patience、Histogram
行级 Diff 的经典目标是找一条较短的编辑脚本(插入/删除序列),而不是还原你的编辑意图。
| 名称 | 直觉 | 常见出处 |
|---|---|---|
| LCS 动态规划 | 最长公共子序列;不在 LCS 中的行视为差异 | 教材、简易实现 |
| Myers | 在编辑图上找最短路径;同长度文本上通常更省内存 | git diff 经典默认 |
| Patience | 先锚定「只出现一次的公共行」,再递归中间区间 | git diff --patience;大块移动/重排时更易读 |
| Histogram | 按出现频次分桶,改进 Patience 对重复行的表现 | 较新 Git 默认之一 |
重要:Diff 结果不唯一。多条同样短的编辑路径都合法,所以两个工具、两个算法对同一对文件给出不同 hunk 很正常——比的是「是否正确标出差异」,不是「是否长得一样」。
一个直观例子:
原文: 修改后:
apple apple
banana cherry
cherry date
date
LCS 可取 apple → cherry → date:呈现为删 banana、在合适位置增一行——不会自动理解成「banana 改名成 cherry」。块移动时若 Diff「看起来很碎」,换 Patience/Histogram(在 Git 里)或先整理行序,往往比肉眼硬读更省事。
时间复杂度直觉
对长度 m、n 的序列,朴素 LCS 约 O(m×n)。日常几千行在浏览器里通常可交互;十万行级会感到卡顿,此时应先切片、或改用本地 git diff / diff -u。
并排视图 vs Unified;行级 vs 字符级
本工具的开关是布局:并排对照,或 unified 上下混排——不是「行级 / 字符级」两种算法模式。
| 粒度 | 适用 | 说明 |
|---|---|---|
| 行级 | 代码、配置 | 先定位变更行;Monaco Diff 的主对齐粒度 |
| 行内字符高亮 | 已变更的行 | Monaco 会在变更行内标出字符差异,便于发现多一个空格、引号 |
| 词级(Git word-diff) | 自然语言修订 | 本页不提供独立词级模式;需要时可在本地用 git diff --word-diff |
回退 UI(Monaco 未加载成功时)退化为按相同行号逐行比对:第 i 行对第 i 行。中间插入一行时,后面所有行都会被标成「修改」——这与 Monaco 的 Myers 类对齐不同,也是实现注记里要强调的边界。
空白、大小写、CRLF:三个噪音源
忽略空白(本工具的真实语义)
勾选 Ignore whitespace 时,每一侧会先按行做 trim()(去掉行首行尾空白),再交给 Diff。它不会:
- 折叠行内多个空格 / Tab 差异(
a bvsa b仍不同) - 等价于
git diff -w/diff -w的「忽略所有空白变更」 - 删除空行或统一缩进风格
YAML、Python、Makefile 等缩进即语义的文本,请保持关闭。散文、部分日志可打开以滤掉行尾空格噪音。需要更强清洗时,先走 空白字符清理,再 Diff。
忽略大小写
勾选后两侧整段 toLowerCase() 再比。适合英文日志级别混用(Error vs error);不适合大小写本身有语义的标识符、HTTP 头名对照(应先统一规范再比)。
CRLF vs LF
Windows 的 \r\n 与 Unix 的 \n 会让「肉眼一样」的两行在字节上不同。Monaco 按文本模型处理换行;若整篇飘红,先统一行尾再比。文末多一个空行、BOM、零宽空格同理——行内字符高亮常能直接暴露。
阅读 Unified Diff / Patch
从 Git 或 diff -u 导出的补丁长这样:
diff --git a/app.conf b/app.conf
--- a/app.conf
+++ b/app.conf
@@ -1,4 +1,5 @@
listen 80;
-server_name example.com;
+server_name www.example.com;
+access_log /var/log/nginx/access.log;
怎么读:
---/+++:旧文件 / 新文件路径(不是内容行)@@ -旧起点,行数 +新起点,行数 @@:hunk 头,定位上下文- 行首空格:上下文(未改)
-/+:删除 / 新增- 连续的删+增块:常是「改了一行」,不要逐符号朗读
若手里已有一份 unified patch、想快速看「+N -M、改了几个文件、大致像 feature 还是 docs」,用 Diff Summary:它解析补丁文本做统计与粗分类,并不做左右两栏文本比对。两栏比对请继续用本页的 文本 Diff。
实际应用场景
场景一:配置文件变更排查
服务异常时,把「上一份正常配置」和「当前配置」贴进 Diff。先确认行尾一致,再开/关忽略空白。Compose / YAML 片段可先用 YAML ↔ JSON 转换 统一风格,或阅读 YAML JSON 指南 理解锚点展开、多文档等「看起来像 Diff、其实是序列化差异」的情况。
场景二:API 响应与 JSON
原始响应字段顺序、缩进不同会产生大片噪音。建议:
- 两侧先 JSON 格式化(必要时键排序)
- 需要语义层(键序无关、树节点级)时用 JSON Diff,并读 JSON Diff 指南
- 文本 Diff 适合「格式已统一后的最后一瞥」或非严格 JSON 的半结构化日志
场景三:翻译与文案
对比译稿是否漏段。大小写混乱时可先 大小写转换。用正则抽出某类行再比时,见 正则指南 与 正则测试器。
场景四:环境差异与清单类文本
.env.production vs .env.staging、crontab -l、两台机器的软件列表——行序不同会被行级 Diff 打成「大段删除+新增」。可先排序或 文本去重 再比,避免误判。
实现注记
以下描述对应本站 DiffTool + DiffViewer 的真实行为(@monaco-editor/react 的 DiffEditor,本地 /monaco-editor/vs 资源),其他网站或 CLI 可能不同:
- 可视化引擎:正常路径为 Monaco DiffEditor(行对齐 + 变更行内字符高亮)。超时未加载时回退为按行号一一对应的简易 unified/并排视图,对齐算法弱于 Monaco,中间插行会导致后续行连锁「修改」。
- 无独立「逐字符模式」开关:字符级信息来自 Monaco 对变更行的内联高亮,不是第二套全文字符 LCS。
- Ignore whitespace:仅
line.trim(),不是diff -w。 - Ignore case:整段小写化后再比。
- 底部统计:
computeDiffStats按相同下标数 added/removed/modified/unchanged,与 Monaco 的最小编辑对齐可以不一致(例如在文件中部插入一行时)。审查以 Diff 视图为准,统计作量级参考。 - 无「忽略匹配行」正则:指南或旧文若提到 ignore pattern,以当前 UI 为准——只有空白与大小写两个开关。
- 纯前端:比对在浏览器完成;输入经
usePersistentState落在本地存储,关闭标签页不会自动当作「已上传服务器」,但共享设备上请 Clear。
FAQ
Diff 工具支持哪些文本格式?
按纯文本比对,不解析语法。代码、JSON、XML、CSV、日志均可。需要语法高亮编辑时,先在编辑器里整理再贴入。
大文件会很慢吗?
几千行通常可交互。接近或超过十万行时,Monaco 与统计都会吃力——切片比对,或改用本地 diff。
会上传我的数据吗?
比对逻辑在浏览器本地执行,不会为了 Diff 把正文 POST 到服务器。本地持久化键仍存在于该浏览器配置中;敏感内容用完请 Clear。
两段文本明明一样,为什么显示有差异?
常见原因:CRLF/LF、文末空行、行尾空格、Tab vs 空格、BOM/零宽字符、一侧多了不可见字符。先关「忽略空白」看真实差异,或用空白清理工具统一后再开 Diff。
和 JSON Diff、Diff Summary 怎么选?
| 需求 | 工具 |
|---|---|
| 任意两段纯文本 / 配置片段 | 文本 Diff |
| 两棵 JSON 树的语义差异 | JSON Diff |
| 已有 unified patch,要增删统计与粗分类 | Diff Summary |
延伸阅读
- JSON Diff 指南 — 键序、数组顺序、大整数精度与语义比对
- JSON 格式化指南 — Diff 前统一缩进与转义形态
- YAML ↔ JSON 指南 — 配置序列化差异为何看起来像「全文变更」
- 正则表达式指南 — 抽取、过滤噪音行后再做文本对比
ToolVault 工具匣 出品的开发者指南。其他在线工具可在 首页 找到。
相关工具
相关文章
Markdown 转 Word 交付指南:样式映射与行内降级
把 Markdown 草稿变成可交付的 .docx:pandoc 命令行与浏览器本地转换两条路线,标题/表格/代码块的 Word 原生样式映射对照,行内格式降级清单,以及「可编辑」为什么比「看起来像」更重要。
Word 转 Markdown 怎么转才干净:两条路线与格式保真对照
docx 转 Markdown 教程:pandoc 命令行与浏览器本地转换两条路线对比,标题/表格/图片/自动编号的保真行为,.doc 旧格式、图片体积、合并单元格等常见坑的解法。
中国车牌号规则与校验:普通牌、新能源与特殊格式全解
中国大陆车牌号编码规则详解:普通蓝牌、新能源 GA36D-2018、武警与使馆牌的结构、省份简称与发牌机关编码,附在线校验方法。