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

React实现不区分大小写的文本高亮匹配方案

React实现不区分大小写的文本高亮匹配改造方案

原Highlighter组件只能匹配大小写完全一致的内容,比如传highlight="Text"时,没法高亮文本里的text。要做到不区分大小写的高亮,得从正则配置和字符串处理两方面改代码,同时还得保留原文本的大小写格式,不能把匹配到的内容改成highlight的大小写。

关键修改点

  • 给正则加上i(不区分大小写)标志,同时转义highlight里的正则特殊字符(比如.、*这些),不然碰到特殊字符会匹配出错
  • 统一匹配和分割用的正则规则,避免两边逻辑不一致
  • 保留原文本里匹配内容的原始大小写,别替换成highlight的大小写

修改后的完整代码

import React from "react";

// 转义正则特殊字符,避免高亮内容含特殊字符时匹配异常
const escapeRegExp = (str) => {
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
};

const Highlighter = ({
  children,
  highlight,
}: {
  children: string;
  highlight: string;
}) => {
  if (!highlight) return <div className="highlighter">{children}</div>;
  
  const escapedHighlight = escapeRegExp(highlight);
  // gi标志:g全局匹配,i不区分大小写
  const regexp = new RegExp(escapedHighlight, "gi");
  const matches = children.toString().match(regexp) || [];
  // 分割用同一个正则,保证逻辑一致
  const parts = children.toString().split(regexp);

  for (let i = 0; i < parts.length; i++) {
    if (i !== parts.length - 1) {
      let match = matches[i];
      // 合并连续空分割后的匹配内容,避免出现多个空span
      while (parts[i + 1] === "") {
        match += matches[++i];
      }

      parts[i] = (
        <React.Fragment key={i}>
          {parts[i]}
          <span className="highlighted">{match}</span>
        </React.Fragment>
      );
    }
  }
  return <div className="highlighter">{parts}</div>;
};

export default Highlighter;

修改细节说明

  1. 新增转义函数:escapeRegExp用来处理highlight里的正则特殊字符,比如如果高亮内容是te.t,不转义的话会匹配text、teat等内容,转义后只会匹配te.t本身。
  2. 正则标志调整:gi组合标志让正则全局搜索且忽略大小写,不管highlight是大写还是小写,都能匹配到目标文本里对应内容。
  3. 类型严谨化:把children和highlight的类型从any改成string,避免传入非字符串类型导致报错。
  4. 空值兜底:给matches加|| [],防止没有匹配结果时出现undefined错误。

使用示例

// 不管highlight传"text"还是"Text",都能高亮文本里的"text"
<Highlighter highlight="Text">
    This is some random text
</Highlighter>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 23:06:26