基于replace方法实现类浏览器Ctrl+F的大小写不敏感文本高亮
文本高亮问题:保留原文本大小写的大小写不敏感匹配
需求
通过replace方法实现文本高亮,要求:
- 支持任意搜索字符串的大小写不敏感匹配
- 高亮时保留原文本的大小写状态,效果类似浏览器Ctrl+F的高亮
当前实现问题
现有代码在搜索字符(比如P)时,所有匹配到的字符都会被替换为搜索字符串的大小写(比如大写P),破坏了原文本的大小写格式。
正确效果

错误效果

现有代码
DataHighlighting.tsx
interface Props { data: string; searchString: string; } const DataHighlighting = ({ data, searchString }: Props): JSX.Element => { const regex = new RegExp(searchString, "gi"); return ( <span dangerouslySetInnerHTML={{ __html: data.replace( regex, `<span style="background: #ff0">${searchString}</span>` ) }} ></span> ); }; export default DataHighlighting;
App.tsx
import "./styles.css"; import DataHighlighting from "./DataHighlighting"; export default function App() { return ( <div className="App"> Programming learning programming for Programming up <div /> <DataHighlighting data="Programming learning programming for Programming up" searchString="P" /> <div /> <DataHighlighting data="Programming learning programming for Programming up" searchString="programming" /> <div /> </div> ); }
解决方案
问题核心是替换逻辑错误:直接用searchString覆盖匹配内容,导致原文本大小写丢失。正确做法是通过正则捕获组引用原匹配文本,再包裹高亮标签。
修改后的DataHighlighting.tsx代码:
interface Props { data: string; searchString: string; } const DataHighlighting = ({ data, searchString }: Props): JSX.Element => { // 转义搜索字符串中的正则特殊字符,避免匹配异常 const escapedSearch = searchString.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // 用捕获组包裹搜索内容,保留原匹配文本 const regex = new RegExp(`(${escapedSearch})`, "gi"); return ( <span dangerouslySetInnerHTML={{ __html: data.replace(regex, `<span style="background: #ff0">$1</span>`) }} ></span> ); }; export default DataHighlighting;
关键修改说明
- 正则转义:处理搜索字符串中的特殊字符(如
.,*,?),避免这些字符被当作正则语法解析,导致匹配偏差。 - 捕获组与
$1引用:用(${escapedSearch})创建捕获组,替换时通过$1调用匹配到的原文本内容,既实现大小写不敏感匹配,又完整保留原文本的大小写状态。
内容的提问来源于stack exchange,提问作者Виктория
相关产品推荐
相关产品推荐

