如何实现Markdown文本关键词高亮且跳过链接括号内的URL内容
需求背景
现有一段Markdown字符串示例:Status of app [TODO app](url.com/apps/list?appid=q1w2e3) has been changed to completed.
需要实现以下功能:
- 对搜索到的关键词用
<mark></mark>标签包裹高亮 - 跳过Markdown链接中圆括号内的URL部分,仅高亮正文和方括号内的链接文本,避免URL内部内容被误高亮
- 不需要匹配完整独立关键词,例如搜索
app时也需要高亮apps中的app片段,适配用户搜索场景
原有代码问题
原有实现会全局匹配关键词,导致URL内部的匹配片段也被错误添加高亮标签,不符合需求。原有代码如下:
const garbage = /[|\\{}()[\]^$+*?.]/g; const highlightMarkdown = (originalString = '', highlight = '') => { highlight = highlight.trim(); if (!highlight) return originalString; const wordsToFind = highlight.replace(garbage, '').split(' '); const result = wordsToFind.reduce((result, word) => { const re = new RegExp(`(${word})`, 'gi'); return result.replace(re, (word) => `<mark>${word}</mark>`); }, originalString); return result; };
修复后实现
通过正则优先匹配圆括号包裹的URL段,仅对非URL段的关键词做高亮处理:
const garbage = /[|\\{}()[\]^$+*?.]/g; const highlightMarkdown = (originalString = '', highlight = '') => { highlight = highlight.trim(); if (!highlight) return originalString; const wordsToFind = highlight.replace(garbage, '').split(' ').filter(Boolean); if (!wordsToFind.length) return originalString; // 正则优先匹配()包裹的链接URL,再匹配目标关键词 const matchPattern = new RegExp(`(\\([^)]+\\))|(${wordsToFind.join('|')})`, 'gi'); return originalString.replace(matchPattern, (match, urlSegment, keyword) => { // 匹配到URL段直接返回原内容 if (urlSegment) return urlSegment; // 匹配到关键词添加高亮标签 if (keyword) return `<mark>${keyword}</mark>`; return match; }); }; // 测试 const result = highlightMarkdown( `Status of app [TODO app](url.com/apps/list?appid=q1w2e3) has been changed to completed.`, 'app' ); console.log(result);
输出结果
运行测试用例后输出内容如下,完全符合需求:Status of <mark>app</mark> [TODO <mark>app</mark>](url.com/apps/list?appid=q1w2e3) has been changed to completed.
内容的提问来源于stack exchange,提问作者glaos
相关产品推荐
相关产品推荐

