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

正则表达式功能异常,求实现字符串指定部分标记的解决方案

问题分析与解决方案

原函数无法满足需求的核心原因有三点:

  • 使用\b单词边界限制,导致无法匹配非单词边界的子串(比如wf无法匹配wfo开头的wf)。
  • 未按片段长度优先级匹配,短片段会抢占字符导致长片段无法匹配。
  • 逐个替换会导致已插入的<mark>标签内容被重复匹配,同时无法处理重叠/交叉匹配的情况。

修正后的函数

const markPartOfString = (string, substrings) => {
  if (!substrings) return string;

  // 解析所有需要匹配的独立片段:逗号分割后按空格拆分,去重过滤空值
  const fragments = substrings.split(',')
    .map(item => item.trim())
    .flatMap(item => item.split(/\s+/))
    .filter(Boolean)
    .filter((value, index, self) => self.indexOf(value) === index);

  if (fragments.length === 0) return string;

  // 按片段长度降序排序,优先匹配长片段避免截断
  const sortedFragments = [...fragments].sort((a, b) => b.length - a.length);

  // 转义正则特殊字符,防止匹配异常
  const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');

  // 收集所有不重叠的匹配位置
  const matches = [];
  sortedFragments.forEach(fragment => {
    const regex = new RegExp(escapeRegExp(fragment), 'gi');
    let match;
    while ((match = regex.exec(string)) !== null) {
      const start = match.index;
      const end = start + match[0].length;
      // 跳过已被覆盖的重叠匹配
      const isOverlapped = matches.some(m => !(end <= m.start || start >= m.end));
      if (!isOverlapped) {
        matches.push({ start, end, text: match[0] });
      }
    }
  });

  // 按起始位置排序匹配结果
  matches.sort((a, b) => a.start - b.start);

  // 构建带标记的结果字符串
  let result = '';
  let lastIndex = 0;
  matches.forEach(match => {
    if (match.start > lastIndex) {
      result += string.slice(lastIndex, match.start);
    }
    result += `<mark>${match.text}</mark>`;
    lastIndex = match.end;
  });
  if (lastIndex < string.length) {
    result += string.slice(lastIndex);
  }

  // 转义HTML实体,符合示例输出格式
  return result.replace(/</g, '&lt;').replace(/>/g, '&gt;');
};

// 测试用例验证
console.log(markPartOfString("wfo test3", "wfo test, wfo test3, wf te")); // &lt;mark&gt;wfo&lt;/mark&gt; &lt;mark&gt;test3&lt;/mark&gt;
console.log(markPartOfString("wfo test", "wf")); // &lt;mark&gt;wf&lt;/mark&gt;o test
console.log(markPartOfString("wfo test", "wf te")); // &lt;mark&gt;wf&lt;/mark&gt;o &lt;mark&gt;te&lt;/mark&gt;st
console.log(markPartOfString("wfo test", "wfo")); // &lt;mark&gt;wfo&lt;/mark&gt; test
console.log(markPartOfString("wfo test", "o st")); // wf&lt;mark&gt;o&lt;/mark&gt; &lt;mark&gt;st&lt;/mark&gt;est

关键改进点

  1. 片段解析与去重:将输入的子串拆分为独立匹配单元,避免重复匹配相同内容。
  2. 长片段优先匹配:按长度排序确保长片段先被匹配,防止短片段截断长片段的匹配(比如优先匹配wfo而非wf)。
  3. 基于索引的位置匹配:在原始字符串上收集所有不重叠的匹配位置,避免已插入的标签内容被重复匹配。
  4. 正则特殊字符转义:确保包含.、*、+等特殊字符的片段能正确匹配原始内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 23:01:30