You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript diff-match-patch库数字差异对比异常问题求助

解决方案:让diff-match-patch将数字作为整体对比

核心思路

diff-match-patch默认的逐字符对比逻辑会拆分数字,要解决这个问题,需要先将文本按「数字/非数字」分割为独立token,让库基于token级对比,再将结果转换回原文本格式。这样数字会被当作一个整体处理,不会被拆分。

具体实现

1. 工具函数:分割与拼接token

先实现两个辅助函数,用于将文本拆分为数字/非数字token,以及用特殊分隔符拼接token(避免与原文本内容冲突):

// 分割文本为数字、非数字独立token
function tokenize(text) {
  // 正则(\d+)会捕获连续数字,split后保留数字和非数字片段,filter过滤空字符串
  return text.split(/(\d+)/).filter(token => token.length > 0);
}

// 用不可见控制字符拼接token,确保diff-match-patch将每个token视为整体
function joinTokens(tokens) {
  return tokens.join('\u0001'); // \u0001是不会出现在普通文本中的控制字符
}

2. 修改后的diff生成函数

基于原函数改造,加入token预处理和后处理逻辑:

function generateDiff(text1, text2) {
  const dmp = new diff_match_patch();
  
  // 预处理:将原始文本转换为token拼接的特殊字符串
  const tokens1 = tokenize(text1);
  const tokens2 = tokenize(text2);
  const tokenText1 = joinTokens(tokens1);
  const tokenText2 = joinTokens(tokens2);
  
  // 基于token文本生成diff(此时每个token被视为一个"字符")
  let diff = dmp.diff_main(tokenText1, tokenText2);
  dmp.diff_cleanupSemantic(diff);
  
  let display1 = '';
  let display2 = '';

  // 遍历diff结果,将token拆回原始内容并生成显示元素
  for (const [op, data] of diff) {
    const tokens = data.split('\u0001').filter(t => t);
    
    for (const token of tokens) {
      const span1 = document.createElement('span');
      const span2 = document.createElement('span');

      if (op === 0) { // 内容相同
        span1.className = 'diff-equal';
        span2.className = 'diff-equal';
        span1.textContent = token;
        span2.textContent = token;
        display1 += span1.outerHTML;
        display2 += span2.outerHTML;
      } else if (op === -1) { // 原文本删除内容
        span1.className = 'diff-delete';
        span1.textContent = token;
        display1 += span1.outerHTML;
      } else { // 新文本新增内容
        span2.className = 'diff-insert';
        span2.textContent = token;
        display2 += span2.outerHTML;
      }
    }
  }

  return [display1, display2];
}

原理说明

  • 预处理阶段:把"1657"和"2160"分别作为独立token,拼接后的字符串让diff-match-patch直接对比整个token,不会拆分字符
  • diff阶段:库会识别到两个数字token完全不同,标记为「删除原数字+插入新数字」
  • 后处理阶段:将token拆回原始内容,生成对应的高亮span,实现你期望的整体数字对比效果

内容的提问来源于stack exchange,提问作者efebeydogan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 13:27:06