TextDiff 是一款免费的在线 diff 工具,用来找出两段文本之间的差异。把两段相似但略有不同的文字并排放在一起——例如文档初稿与修改稿、发出的合同与对方返回的合同、代码的旧版本与新版本——它会用颜色标出哪些行被新增、删除或修改,以及行内具体哪些词或字符发生了变化。
所有比较都在浏览器内完成。您输入的文本和载入的文件不会发送到服务器,因此公司内部文档、合同等不便外传的内容也可以放心比较。计算在 Web Worker 中进行,即使输入数万行,页面也不会卡住。
主要功能
行级 + 行内高亮
先找出变更的行,再在这些行内按词、空格分段或字符,再次高亮真正改动的部分。
分栏与合并视图
可在左右并排的分栏视图(side-by-side)和像 git 一样自上而下阅读的合并视图(unified)之间切换。
忽略选项
比较时可以忽略行尾空白、空白数量、所有空白、大小写和空行。
统一换行符
把 Windows(CRLF)与 macOS、Linux(LF)的换行差异,以及最后一行是否有换行符视为相同。
JSON 键排序比较
解析两段 JSON,对对象的键排序并统一缩进后再比较。仅键的顺序不同时不算作差异。
变更统计与跳转
显示新增、删除、修改的行数和相似度(%),并可直接跳到上一处或下一处变更。
仅显示变更
折叠较长的未改动区域,只保留变更前后各 3 行。点击折叠区域即可展开。
拖放文件
可将 .txt、.md、.json、.csv 以及各种代码文件拖入输入框,或一次拖入两个文件立即比较。
导出 patch 与 HTML
可将结果复制或保存为 unified diff(patch)文本,也可复制为带颜色的 HTML 表格,粘贴到邮件或文档中。
使用方法
- 在左侧框(原文)粘贴作为基准的文本,在右侧框(修改后)粘贴要比较的文本。也可以把文件拖入输入框,或使用输入框上方的打开按钮。
- 开启“输入时即时比较”后,停止输入的瞬间就会显示结果。关闭时请点击[比较]或按 Ctrl+Enter。
- 如有需要,可选择忽略空白、大小写或空行,选择行内比较单位(词/按空格分段/字符),或开启 JSON 键排序。更改选项后会立即重新比较。
- 在结果栏中选择分栏或合并视图,用上下箭头按钮(或 Alt+↑/↓)在各处变更之间跳转。
- 需要分享时,可以复制或保存 patch,或复制为 HTML。
比较选项说明
| 空白:按原样比较 | 空格和制表符与其他字符同等对待。哪怕只差一个缩进,也算作不同的行。 |
|---|---|
| 空白:忽略行尾空白 | 只忽略行尾残留的空格和制表符,可过滤掉编辑器自动删除或保留的空白造成的差异。(类似 GNU diff 的 -Z) |
| 空白:忽略空白数量 | 一个空格和多个空格视为相同。但有空白和没有空白仍然不同:'a b' 与 'a b' 相同,'a b' 与 'ab' 不同。(diff -b) |
| 空白:忽略所有空白 | 先删除全部空白再比较,'a b' 与 'ab' 也视为同一行。(diff -w) |
| 行内比较:词 | 以字母数字串和符号为单位标出变更部分,适合代码和英文文本。 |
| 行内比较:按空格分段 | 以空格分隔的片段为单位标出变更,适合英文、韩文等词与词之间用空格隔开的文字。中文、日文这类不以空格分词的文字,通常按字符比较更有用。 |
| 行内比较:字符 | 逐个字符比较。适合准确找出金额、日期、条款编号等只改了一两个字符的地方。 |
| 忽略大小写 | 将英文大写和小写字母视为同一个字符。 |
| 忽略空行 | 将空行或只含空白的行排除在比较之外。空行以浅色显示,不计入变更数。(类似 diff -B) |
| 统一换行符 | 将 CRLF、CR、LF 都视为同一种换行,并忽略文件末尾是否有换行符。关闭后,行尾的 CR 显示为 ␍,没有结尾换行符的最后一行标记为 ∅。 |
| JSON 键排序 | 将两侧都解析为 JSON,按字典顺序对对象的键排序,并以 2 个空格缩进重新输出后再比较。数组顺序保持不变。解析失败时会提示出错位置。 |
换行符(如 CRLF)的差异只有在从文件载入文本时才能精确比较。粘贴到输入框的文本会被浏览器把换行统一转换为 LF,因此看不到 CR 的差异。
快捷键
Ctrl+Enter / ⌘+Enter | 立即比较 |
Alt+↓ / Alt+↑ | 跳到下一处/上一处变更 |
n / p(在输入框外) | 跳到下一处/上一处变更 |
Tab(在输入框内) | 输入制表符 |
输入内容不会发送到任何地方
比较引擎是随本页面一起下载的 JavaScript(diff-core.js),文本和文件只在浏览器内存中处理。输入内容不会被保存,浏览器只会记住您选择的主题和选项。关闭页面后,输入内容即会消失。
常见问题
要比较的文本会保存在服务器上吗?
不会。比较完全由浏览器中的 JavaScript 完成,输入内容不会发送到任何服务器。页面打开后,即使断开网络也能继续比较。
最大能比较多大的文本?
单个文件最多可载入 30MB。数万行规模的比较也在独立线程(Web Worker)中处理,页面不会卡住。差异非常多时,为了速度可能给出近似结果而非最小结果。结果超过 4,000 行时,会先只显示有变更的部分。
使用的是什么算法?
按行比较采用 Myers(1986)的 O(ND) 差分算法,并以线性空间方式实现。当计算量过大时,会像 GNU diff 一样改用近似分割。在变更的行内,再用同一算法按词、空格分段或字符进行比较。
“修改”和“新增、删除”是怎么区分的?
在一个变更区域内,如果被删除的行与新增的行内容足够相似,就把它们配成一对,视为同一行被修改,计为“修改”。无法配对的行计为“新增”或“删除”。
相似度(%)是怎么计算的?
它是两侧全部字符(含换行符)中未发生变化的字符所占的比例。相同的行全部计入;被修改的行只计入行内保持不变的部分。
“忽略空白数量”和“忽略所有空白”有什么区别?
“忽略空白数量”只忽略空格的个数,因此 'a b' 和 'ab' 仍然不同。“忽略所有空白”会先删除所有空白再比较,因此两者视为相同。在 Python 这类缩进有语法意义的代码中,请谨慎使用“忽略所有空白”。
开启忽略选项后生成的 patch 能应用吗?
patch 根据屏幕上显示的差异生成,上下文行取自原文。开启忽略选项后,被忽略的差异不会写入 patch。若要让文件完全一致,请关闭所有选项后再生成 patch。
能比较 Word、WPS、PDF 文档吗?
无法直接读取这些文件。从文档中复制文本并粘贴进来即可比较,但表格、脚注和格式可能会丢失。具体技巧请参阅文档对比指南。
手机上可以用吗?
可以。在窄屏上,输入框会上下排列,结果默认以合并视图显示,也可以切换到分栏视图。