Java实现文本差分 diff 工具代码

工具类源码

https://github.com/Uetty/common-tool/blob/dev/src/main/java/com/uetty/common/tool/algorithm/diff/LCSDiff.java

使用

LCSDiff lcsDiff = new LCSDiff(str1, str2, new EnglishWordMetadataPicker()); // 元数据的定义:一个英文单词视为一个不可分割单元(元数据),英文字母外的其余字符,单个字符视为一个不可分割单元(元数据)
//        LCSDiff lcsDiff = new LCSDiff(str1, str2);    // 使用默认元数据采拣器的版本:单个char视为一个不可分割单元(元数据)
CommonInfo diff = lcsDiff.seekCommon();

CommonInfo:用于存储公共文本在两个字符串(str1和str2)中的位置
MetadataPicker:用于将字符串str1str2处理为两组元数据组成的数组
元数据:表示在diff的过程中作为一个整体进行匹配的字符串,示例如下:

两个字符串str1和str2如下(为了方便演示,例子中选取的两个字符串都没有空格)
str1: 1+2=3one+two=three
str2: 11+2=13eleven+two=thirteen
定义他们由以下元数据组成(元数据间用空格分隔)
str1: 1 + 2 = 3 one + two = three
str2: 1 1 + 2 = 1 3 eleven + two = thirteen
那么匹配到的共同字符串将会是如下3个字符串:
1+2= 3 +two=
由于str1中的one和str2中的eleven都是元数据,所以one中的e字符和elevent中的e字符不能产生匹配
同理,由于str2中的数字13是由两个元数据1和3组成,所以13中的3能够与str1中等号后面的3产生匹配

元数据采拣器的选取非常重要,会影响diff效果的好坏,元数据采拣器的好坏以业务需求作为评定准则。此外,处理后元数据数组的长度将影响diff算法计算时占用的内存大小。

例如:
对代码进行diff这个业务逻辑,可以考虑用代码中的特殊符号如{};空白字符换行符等代码语句分割符来生成元数据,进行第一次diff。然后再用更细粒度的元数据采拣器,对初次匹配中不一致的行内容再进行一次diff。类似于Idea中的文件比较功能的效果,使用换行符进行第一次匹配,完整行不匹配的,会用一个较浅的颜色标记该行存在差异,再在行内部使用细粒度的差分再次匹配,然后用较深的颜色标记高亮显示出行内部细节上存在差异的点,这样在降低内存占用率的同时,又能让文件的差异一目了然。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值