Html文本比对实现,基于google的diff_match_patch
尝试一下:https://npcdw.github.io/HtmlDiff/
HtmlDiff支持比对两个html,然后生成添加标记的两个html,并保证样式不会乱,支持添加到忽略列表的标签不进行对比
还支持对比后生成一个html(非常不推荐,因为格式可能会错乱,例如两个结构不同的表格对比,不推荐为什么还要做?领导要求的)
效果图如下: 对比两个简单的、没有格式的文本可以直接使用 google 的 diff-match-patch 进行对比。
对比html难点在于
- 如何忽略掉不需要进行对比的标签,只对比标签中间的文本
- 如果修改了样式我们该怎么对比出来
- 对比完文本后,我们该怎样把标签原封不动的分别还原到两段html标签中
我提供的思路只解决了第一条和第三条,关于第二条,没找到解决的方法,所以本文标题才叫做 Html文本对比
下面说一下我的思路和实现:
首先、我们需要保存好两段原始的html文本,以下简称为原始html1和原始html2。
然后、分别创建一个原始html1和原始html2的副本,然后分别将副本的标签去掉,只保留其中的文本,以下简称原始文本1和原始文本2。
第三、使用google的 diff-match-patch 将文本进行对比,对比完成返回的结果样式应该是这样的
[
{
"0": 0,
"1": "Hamlet: Do you see "
},
{
"0": -1,
"1": "yonder cloud"
},
{
"0": 1,
"1": "the cloud over there"
}
]
解释一下:
字符串 "0"
代表对比结果的类型,数字 0
代表相同的文本,-1
代表原始文本1相对于原始文本2删除的文本,1
代表原始文本1相对于原始文本2增加的文本。
字符串 "1"
代表对比结果的文本
这个列表是有顺序的,所有的类型为 0
和类型为 -1
的文本前后拼接起来就是原始文本1,所有的类型为 0
和类型为 1
的文本前后拼接起来就是原始文本2。
我们将所有的类型为 0
和类型为 -1
的列表称为对比列表1,将所有的类型为 0
和类型为 1
的列表称为对比列表2
第四、开始还原原始的 html 文本,并在其中加入插入标签 <ins></ins>
和删除标签 <del></del>
,还原的过程大致如下:
因为两个html文本的还原过程一致,我们只拿第一个举例。
1、创建一个用于还原的html文本,我们称之为还原html
2、我们取出原始html1中的最前面一段,选取的规则是取出一段【文本】,如果一开始就是文本,而非标签(开始标签和结束标签都算标签),那么就取这段文本,遇到标签结束,如果一开始就是标签,那么取出这段标签和之后遇到文本,同样是遇到下一段标签结束,例如:
</span><div></div><div><p>这是一块文本
我们将取出的标签和文本称之为选取标签和选取文本
3、将选取标签直接追加到还原文本末尾,将选取文本与对比列表中的第一段文本(以下简称第一段对比文本)进行对比,
- 如果选取文本等于第一段对比文本,将选取文本追加到还原文本末尾,删除原始html的选取部分,删除选取列表的第一块
- 如果选取文本小于第一段对比文本,将选取文本追加到还原文本末尾,删除原始html的选取部分,删除第一段对比文本中选取文本的部分,再取出原始html文本。。。。。重复此过程
- 如果选取文本大于第一段对比文本,将第一段对比文本追加到还原文本末尾,删除选取文本中第一段对比文本的部分,删除选取列表的第一块,再取出选取列表的第一块,再与选取文本对比。。。。重复此过程
直到原始html的长度变成0,或对比列表的长度变成0,直接将剩下的部分都追加到还原文本末尾,那么还原的过程就结束了。