前端开发中非常常见的场景,当用户在搜索框输入关键词后,页面中匹配到关键词的文本,需要高亮展示。举个最直观的例子:
原始文本:'今天的天气不错'
用户搜索:'天'
很多人第一反应是:对原始文本进行子串比对,找到所有匹配关键词的位置,然后将文本拆分成多个独立的片段,再给匹配到的片段包裹上带高亮样式的容器。这种方法确实能实现效果,但过程非常繁琐。
既然是“处理字符串匹配”,那自然会想到正则表达式。我们完全可以用极简的代码实现这个需求。
不绕弯子,直接上最终实现代码(React场景):
// 核心代码,仅1行JSX逻辑 text.split(new RegExp(`(${searchKey})`, 'gi')).map((str, i) => i % 2 ? <span key={i} style={{ background: 'yellow' }}>{str}</span> : str )正则表达式与split方法的结合
new RegExp(`(${searchKey})`, 'gi')这里有两个关键要点:
分组符 ():这是整个实现的“灵魂”。
正常情况下,split方法会根据匹配到的内容拆分字符串,并丢弃匹配到的子串(比如用“天”拆分“今天的天气不错”,会得到["今", "的", "气不错"])。
但加上分组符后,split会将匹配到的子串也保留在拆分后的数组中。
所有匹配到的关键词(“天”)都在奇数索引位置(索引1、3),而其他非匹配文本都在偶数索引位置(索引0、2、4)。
["今", "天", "的", "天", "气不错"]
修饰符 gi:g表示“全局匹配”,i表示“忽略大小写”。
JSX与map方法的结合
实现高亮渲染,这里JSX的特性功不可没——它可以和原生JavaScript代码无缝混写,我们不需要额外的模板语法。JSX的便捷之处,我在这篇文章中已有介绍:Vue和React之争
最后,正则表达式中的分组符()还有很多实用用途,比如捕获匹配内容、实现分组替换等,以后有机会我再专门整理一篇文章,详细讲解正则分组的各种用法。
作者简介:从事 Web 前后端开发多年。一直相信“技术应该被说人话”,坚持输出实用易懂的干货内容。闲暇写些随笔,记录行业观察与生活感悟。