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

纯JS文本高亮函数Bug修复请求:连续关键词匹配异常

修复JavaScript文本高亮函数realcar的连续关键词匹配Bug

问题概述

这款纯JavaScript实现的realcar函数具备无框架依赖、大小写不敏感、支持HTML标签内容高亮的特性,但搜索连续关键词(如"word high")时存在Bug:第二个关键词会被替换为文本片段中最后一个空格后的其他词汇,而非目标搜索词。

Bug根源分析

  1. 数组引用污染:RegExpUNICO直接引用了原关键词数组wordss,在匹配循环中不断向其中push匹配到的文本,导致后续正则表达式被无关内容污染。
  2. 错误的位置定位:使用nodeValue.indexOf(parts[n-1])获取高亮文本起始位置,若文本存在重复片段,会取到第一个匹配位置,导致高亮内容错位。
  3. 冗余的正则重构:在匹配后重复构建正则的逻辑完全多余,反而打乱了原有的关键词匹配规则。

修复后的完整代码

HTMLElement.prototype.realcar = function(word) {
  const el = this;
  // 处理关键词:去重、过滤短词(长度>2)
  const wordss = word.trim().sanitiza().split(" ").filter(word1 => word1.length > 2);
  // 避免空关键词数组导致正则报错
  if (wordss.length === 0) return;
  
  // 构建初始正则:大小写不敏感,全局匹配
  const regex = new RegExp(wordss.join('|'), 'ig');
  const nodes = Array.from(el.childNodes);

  for (let i = 0; i < nodes.length; i++) {
    const node = nodes[i];

    if (node.nodeType === 3) {
      const nodeValue = node.nodeValue;
      const matches = [];
      let match;
      // 存储所有匹配项的位置和内容
      while ((match = regex.exec(nodeValue.sanitiza())) !== null) {
        matches.push({
          value: match[0],
          index: match.index
        });
        // 修复正则lastIndex导致的无限循环问题
        if (match[0].length === 0) regex.lastIndex++;
      }

      if (matches.length > 0) {
        let lastIndex = 0;
        // 遍历匹配结果,分割文本并插入高亮节点
        matches.forEach(match => {
          // 插入匹配前的普通文本
          if (lastIndex < match.index) {
            const textPart = nodeValue.substring(lastIndex, match.index);
            el.insertBefore(document.createTextNode(textPart), node);
          }
          // 创建高亮节点
          const highLightNode = document.createElement("hightx");
          highLightNode.style.border = '1px solid blue';
          highLightNode.style.backgroundColor = '#ffea80';
          highLightNode.appendChild(document.createTextNode(match.value));
          el.insertBefore(highLightNode, node);
          // 更新最后位置
          lastIndex = match.index + match.value.length;
        });
        // 插入剩余的普通文本
        if (lastIndex < nodeValue.length) {
          const textPart = nodeValue.substring(lastIndex);
          el.insertBefore(document.createTextNode(textPart), node);
        }
        // 移除原文本节点
        el.removeChild(node);
      }
    } else {
      // 递归处理子元素
      node.realcar(word);
    }
  }
}

关键修改说明

  1. 数组隔离:不再直接引用原关键词数组,避免后续操作污染初始关键词列表。
  2. 精准匹配存储:记录每个匹配项的index和value,确保高亮位置绝对准确,彻底解决错位问题。
  3. 简化逻辑:移除冗余的正则重构步骤,直接使用初始关键词正则进行匹配,逻辑更清晰。
  4. 修复正则循环问题:处理匹配空字符串的极端情况,避免正则lastIndex导致的无限循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 03:17:13