.NET中利用diff库识别文本最后新增内容的实现问询
解决方案
要实现区分两次新增内容并标记最后一次新增的需求,核心思路是分两次对比版本差异:先对比初始版本与中间版本,得到第一次新增的内容;再对比中间版本与最终版本,提取最后一次新增的内容并替换为自定义操作码。具体实现步骤如下:
实现步骤
- 生成两组差异对比结果:
- 对比
s1(初始)和s2(中间版本),得到第一次修改的差异 - 对比
s2(中间版本)和s3(最终版本),得到第二次修改的差异
- 对比
- 处理第二次对比的结果:将其中的
INSERT操作(操作码1)替换为自定义操作码4 - 合并两组有效差异结果,过滤掉重复的平等内容
完整代码示例
string s1 = "the Charterers as follows: "; string s2 = "the Charterers as follows: added"; string s3 = "the Charterers as follows: added new content again"; diff_match_patch dmp = new diff_match_patch(); List<NewDiff> newDiffList = new List<NewDiff>(); // 第一步:对比s1和s2,获取第一次修改的差异 List<Diff> diffS1S2 = dmp.diff_main(s1, s2); dmp.diff_cleanupSemantic(diffS1S2); foreach (var diffItem in diffS1S2) { newDiffList.Add(new NewDiff { Operation = diffItem.operation, Text = diffItem.text }); } // 第二步:对比s2和s3,获取第二次修改的差异 List<Diff> diffS2S3 = dmp.diff_main(s2, s3); dmp.diff_cleanupSemantic(diffS2S3); foreach (var diffItem in diffS2S3) { // 仅保留新增内容,将操作码替换为4 if (diffItem.operation == 1) { newDiffList.Add(new NewDiff { Operation = 4, Text = diffItem.text }); } // 平等内容无需重复添加,因为s1→s2的结果已包含s2的全部内容 } // 输出结果(可根据需求序列化为JSON)
代码说明
- 分两次对比:避免直接对比
s1和s3导致无法区分两次新增的内容,确保每一次版本迭代的修改都能被单独识别 - 操作码替换:将
s2到s3的新增操作(原操作码1)替换为自定义操作码4,精准标记最后一次新增内容 - 语义清理:调用
diff_cleanupSemantic优化差异结果,合并相邻的相同操作,让输出更符合阅读逻辑
扩展场景处理
如果中间版本到最终版本存在删除或修改操作(非纯新增),可以根据需求调整逻辑:
- 对于删除操作(原操作码0):可保留原操作码,或自定义其他标识
- 对于修改操作:可拆分为
DELETE+INSERT,将其中的INSERT部分标记为4(根据业务需求定义)
内容的提问来源于stack exchange,提问作者Niranjan
相关产品推荐
相关产品推荐

