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

JavaScript 如何实现重叠匹配的字符串高亮显示功能

问题描述

假设我们有如下字符串:

"The quick brown fox jumps over the lazy dog"

如果在该字符串中搜索关键词 "ove ver",预期结果是单词 "over" 被高亮标记。

现有实现代码如下:

'The quick brown fox jumps over the lazy dog'
    .replace(/ove|ver/g, s => s.replace(/\w/g, '<mark>$&</mark>'))

补充说明:搜索单字符 "o" 时不需要高亮到下一个单词边界,预期输出结果为:
"The quick br<mark>o</mark>wn f<mark>o</mark>x jumps <mark>o</mark>ver the lazy d<mark>o</mark>g"


解决方案

核心问题是普通全局正则匹配无法处理重叠的匹配项(比如over中的ove和ver存在字符重叠,第一个匹配会吃掉重叠字符导致第二个匹配失败),可以通过先标记所有需要高亮的字符位置,再统一插入标签的方式实现:

function highlightKeyword(str, keyword) {
  // 转义正则特殊字符,避免注入风险
  const escapeRegExp = s => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  // 按空格拆分关键词为多个子匹配模式
  const patterns = keyword.trim().split(/\s+/).map(escapeRegExp)
  if (patterns.length === 0) return str

  // 构造支持重叠匹配的正向零宽断言正则
  const regex = new RegExp(`(?=(${patterns.join('|')}))`, 'g')
  // 初始化高亮位置标记数组
  const highlightFlags = new Array(str.length).fill(false)

  let match
  while ((match = regex.exec(str)) !== null) {
    const matchLen = match[1].length
    const startIndex = match.index
    // 标记所有匹配到的字符位置
    for (let i = startIndex; i < startIndex + matchLen; i++) {
      highlightFlags[i] = true
    }
    // 避免零宽匹配导致的死循环
    if (match[0] === '') regex.lastIndex++
  }

  // 遍历字符串拼接高亮标签
  let result = ''
  let inHighlight = false
  for (let i = 0; i < str.length; i++) {
    if (highlightFlags[i] && !inHighlight) {
      result += '<mark>'
      inHighlight = true
    } else if (!highlightFlags[i] && inHighlight) {
      result += '</mark>'
      inHighlight = false
    }
    result += str[i]
  }
  // 处理末尾仍处于高亮状态的边界情况
  if (inHighlight) result += '</mark>'
  return result
}

// 测试用例
const testStr = 'The quick brown fox jumps over the lazy dog'
// 测试多关键词重叠匹配
console.log(highlightKeyword(testStr, 'ove ver'))
// 输出:The quick brown fox jumps <mark>over</mark> the lazy dog

// 测试单字符匹配
console.log(highlightKeyword(testStr, 'o'))
// 输出:The quick br<mark>o</mark>wn f<mark>o</mark>x jumps <mark>o</mark>ver the lazy d<mark>o</mark>g

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 05:15:03