前端实现文本对比并高亮显示差异的方法

 更新时间:2024年09月29日 08:57:13   作者:李牌牌you  
文本对比是一个常见需求,尤其在版本控制和代码编辑中,本文介绍了如何使用jsdiff库和diff2html工具来实现文本内容的差异比较和美化显示,文中通过图文介绍的非常详细,需要的朋友可以参考下

你有没有想过,常见的代码差异对比是如何都实现的呢?其实这里面涉及到非常复杂的文本对比算法,本文就来看看如何通过现有工具库 jsdiff + diff2html 实现文本对比,并高亮显示差异!

文本对比

文本对比可以借助 jsdiff 来实现,jsdiff 是一个 JavaScript 库,用于实现文本差异比较。这个库提供了多种方法来计算和展示两个文本之间的差异,可以用于多种文本差异比较的场景,比如版本控制、文档比较、代码编辑器中的变更高亮等。

jsdiff 基于 Myers 在 1986 年提出的 "An O(ND) Difference Algorithm and its Variations" 算法实现。

jsdiff 是一个非常热门的工具库,其 npm 周下载量高达 4000 万,很多知名前端工具库都依赖它:

Github:https://github.com/kpdecker/jsdiff

以下是 jsdiff 提供的 API:

  • diffChars - 对两个文本进行字符级别的差异比较。

  • diffWords - 对两个文本进行单词级别的差异比较,忽略空白字符。

  • diffWordsWithSpace - 对两个文本进行单词级别的差异比较,考虑空白字符作为分隔符。

  • diffLines - 对两个文本按行进行差异比较。

  • diffSentences - 对两个文本按句子进行差异比较。

  • diffCss - 专门用于比较 CSS 代码的差异。

  • diffJson - 比较两个 JSON 对象的差异,首先将它们序列化为格式化的 JSON 文本,然后逐行比较。

  • diffArrays - 比较两个数组,检查数组元素的严格等同性。

  • createTwoFilesPatch - 创建一个包含两个文件差异的补丁。

  • createPatch - 创建一个补丁,通常用于一个文件的前后变化。

  • applyPatch - 应用一个给定的补丁到源文本上。

  • applyPatches - 应用一个或多个补丁到相应的文件内容上。

  • parsePatch - 解析一个补丁字符串为结构化的数据。

  • reversePatch - 反转一个补丁,使得应用此补丁会撤销原始的更改。

  • convertChangesToXML - 将差异对象转换为 XML 格式。

  • convertChangesToDMP - 将差异对象转换为 Google 的 diff-match-patch 库的格式。

在使用 jsdiff 时,首先需要通过以下命令来安装:

npm install diff --save

安装完成之后就可以选择合适的 API 直接使用了。对于文章最开始的例子,就可以借助 createTwoFilesPatch API 来对比两个文件的差异,它的参数如下:

createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options)
  • oldFileName: 旧文件的文件名。

  • newFileName: 新文件的文件名。

  • oldStr: 原始字符串值

  • newStr: 新的字符串值

  • oldHeader: 可选,允许在旧文件的头部添加额外的信息。

  • newHeader: 可选,用于在新文件的头部添加额外的信息。

  • options: 一个包含选项的对象,可以用来自定义补丁的生成方式:

    • context: 描述应该包含多少行上下文。设置为 Number.MAX_SAFE_INTEGER 或 Infinity 可以包含整个文件内容在一个块(hunk)中。

    • ignoreWhitespace: 与 diffLines 中的用法相同,用于忽略空白字符差异。默认为 false

    • stripTrailingCr: 与 diffLines 中的用法相同,用于在执行差异比较之前去除所有尾随的回车符(\r)。这有助于在比较 UNIX 和 Windows 文本文件时得到有用的差异结果。默认为 false

代码如下:

import * as Diff from 'diff';

const oldFile = `{
  "projectName": "ExampleProject",
  "version": "1.0.0",
  "author": "John Doe",
  "dependencies": {
    "libraryA": "^1.2.3",
    "libraryB": "^3.4.5"
  },
  "devDependencies": {
    "toolX": "^0.9.8"
  },
  "scripts": {
    "start": "node index.js"
  }
}`; 

const newFile = `{
  "projectName": "ExampleProject",
  "version": "1.0.1",
  "author": "Jane Doe",
  "dependencies": {
    "libraryA": "^1.2.3",
    "libraryC": "^7.8.9"
  },
  "devDependencies": {
    "toolX": "^0.9.8",
    "toolY": "^2.3.4"
  },
  "scripts": {
    "start": "node app.js",
    "test": "npm test"
  }
}`;

const diff = Diff.createTwoFilesPatch("旧文件", "新文件", oldFile, newFile);

这里的对比结果 diff 结果如下:

对比结果有点丑,下面会进行优化。

除了 jsdiff,还有一个基于 jsdiff 开发的 React 库:react-diff-viewer。它提供了一种简单易用的方式来展示两个文本或对象之间的差异,不仅可以对文本进行对比,还可以输出漂亮的差异对比结果。

Github:https://github.com/praneshr/react-diff-viewer

高亮显示差异

如果使用 jsdiff 进行对比,对比结果可能没那么美观,可以借助 diff2html 来美化。

diff2html 是一个用于将差异(diff)结果转换成 HTML 格式的工具,它通常用于在网页上展示文件或文本内容之间的差异。这个库提供了一种方便的方式来生成美观的差异比较视图,使得用户可以轻松地查看和理解两个版本之间的变化。

Github:https://github.com/rtfpessoa/diff2html

首先需要进行安装:

npm install diff2html --save

然后导入使用即可:

import * as Diff2Html from "diff2html";

const outputHtml = Diff2Html.html(diff, {
  inputFormat: "diff",
  showFiles: true,
  matching: "lines",
  highlight: true,
  outputFormat: "side-by-side",
});

这里的 diff 就是上一步中生成的 diff 结果。

美化后对比如下,更美观了:

更多配置可以在其文档中进行探索。

总结

到此这篇关于前端实现文本对比并高亮显示差异的文章就介绍到这了,更多相关前端文本对比高亮显示差异内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • javascript 中iframe高度自适应(同域)实例详解

    javascript 中iframe高度自适应(同域)实例详解

    这篇文章主要介绍了javascript 中iframe高度自适应(同域)实现代码的相关资料,需要的朋友可以参考下
    2017-05-05
  • JSON中双引号的轮回使用过程中一定要小心

    JSON中双引号的轮回使用过程中一定要小心

    如果JSON对象中有属性是包含双引号当转换成字符串形式,将自动加上反斜线,详细请祥看本文
    2014-03-03
  • JavaScript轻松创建级联函数的方法示例

    JavaScript轻松创建级联函数的方法示例

    级联函数也叫链式函数,方法链一般适合对一个对象进行连续操作 (集中在一句代码)。一定程度上可以减少代码量,缺点是它占用了 函数的返回值。下面这篇文章主要给大家介绍了利用JavaScript如何轻松创建级联函数的方法示例,需要的朋友可以参考借鉴。
    2017-02-02
  • 浅谈js原生拖放

    浅谈js原生拖放

    下面小编就为大家带来一篇浅谈js原生拖放。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11
  • 微信小程序实现下拉框功能

    微信小程序实现下拉框功能

    这篇文章主要为大家详细介绍了微信小程序实现下拉框功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • 一文带你深入了解JavaScript中的闭包

    一文带你深入了解JavaScript中的闭包

    闭包(closure)是一个函数以及其捆绑的周边环境状态的引用的组合,就是让开发者可以从内部函数访问外部函数的作用域,下面下面小编就来和大家深入聊聊它的使用吧
    2023-07-07
  • 详解JavaScript中Promise类的使用方法

    详解JavaScript中Promise类的使用方法

    这篇文章主要为大家详细介绍了JavaScript中Promise类的使用方法,文中的示例代码简洁易懂,对我们学习JavaScript有一定的帮助,需要的可以参考一下
    2023-05-05
  • 限制只能输入数字的实现代码

    限制只能输入数字的实现代码

    下面小编就为大家带来一篇限制只能输入数字的实现代码。小编觉得挺不错的,现在分享给大家,也给大家做个参考,一起跟随小编过来看看吧
    2016-05-05
  • javascript 在firebug调试时用console.log的方法

    javascript 在firebug调试时用console.log的方法

    当你使用console.log()函数时,下面的firebug一定要打开,不然这函数在用firefox运行时无效且影响正常程序,如果用IE打开,将会出错
    2012-05-05
  • JS对大量数据进行多重过滤的方法

    JS对大量数据进行多重过滤的方法

    今天在工作中遇到一个问题,当前端通过Ajax从后端取得了大量的数据,需要根据一些条件过滤,但是发现写的过滤方法有问题,后来仔细的查找问题,通过网上的资料终于解决了这个问题,现在将解决的过程以及解决方法分享给大家,有需要的朋友们可以参考借鉴。
    2016-11-11

最新评论