react实现单词高亮
实现单词高亮的基本思路
在React中实现单词高亮的核心逻辑是通过字符串替换或正则表达式匹配目标单词,将其包裹在带有高亮样式的HTML元素(如<span>)中。需要处理动态输入、大小写敏感等场景。
使用字符串替换方法
将目标文本按关键词拆分后重新组合,为匹配部分添加高亮样式。以下是一个基础实现示例:

function HighlightText({ text, keyword }) {
if (!keyword) return text;
const parts = text.split(new RegExp(`(${keyword})`, 'gi'));
return (
<>
{parts.map((part, i) =>
part.toLowerCase() === keyword.toLowerCase() ? (
<span key={i} style={{ backgroundColor: 'yellow' }}>
{part}
</span>
) : (
part
)
)}
</>
);
}
正则表达式匹配复杂场景
需要处理特殊字符或多单词匹配时,需对关键词进行转义并优化正则:
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
function HighlightText({ text, keywords }) {
if (!keywords.length) return text;
const regex = new RegExp(
`(${keywords.map(escapeRegExp).join('|')})`,
'gi'
);
const parts = text.split(regex);
return (
<>
{parts.map((part, i) =>
keywords.some(k =>
k.toLowerCase() === part.toLowerCase()
) ? (
<span key={i} className="highlight">{part}</span>
) : (
part
)
)}
</>
);
}
样式与性能优化
通过CSS类名控制高亮样式更易于维护:

.highlight {
background-color: #ffeb3b;
font-weight: bold;
padding: 0 2px;
}
对于长文本或高频更新场景,考虑使用useMemo优化:
const highlightedText = useMemo(() => {
// 高亮处理逻辑
}, [text, keywords]);
支持富文本与安全处理
若文本包含HTML标签,需使用DOMPurify等库防止XSS攻击:
import DOMPurify from 'dompurify';
function sanitizeAndHighlight(text, keyword) {
const sanitized = DOMPurify.sanitize(text);
// 高亮处理逻辑
}
完整组件示例
import React, { useMemo } from 'react';
import DOMPurify from 'dompurify';
function HighlightText({ text, keywords = [], caseSensitive = false }) {
const highlighted = useMemo(() => {
if (!keywords.length) return text;
const flags = caseSensitive ? 'g' : 'gi';
const pattern = `(${keywords.map(escapeRegExp).join('|')})`;
const regex = new RegExp(pattern, flags);
return DOMPurify.sanitize(text).split(regex).map((part, i) => {
const isMatch = keywords.some(k =>
caseSensitive
? k === part
: k.toLowerCase() === part.toLowerCase()
);
return isMatch ? (
<span key={i} className="highlight">{part}</span>
) : part;
});
}, [text, keywords, caseSensitive]);
return <>{highlighted}</>;
}






