在Python中实现不区分大小写的文本高亮,核心是先找到所有目标关键词在原文中的匹配位置,再对对应区间的内容添加高亮标记,同时要处理关键词边界,避免把长词中的子串误判为匹配项。

核心实现思路
整个流程可以分为三个步骤:首先将原文和目标关键词统一转为小写(或大写)进行匹配,找到所有符合要求的匹配区间;其次对匹配区间做边界校验,确保匹配的是完整的关键词而不是其他词的子串;最后按照匹配区间的位置,对原文进行分段处理,给匹配区间的内容添加高亮标记。
边界定位的实现逻辑
边界定位的目的是保证匹配的关键词是独立的词,而不是其他更长词的组成部分。我们可以通过正则表达式的单词边界符b来实现,同时结合不区分大小写的匹配模式,就能精准定位到目标关键词的完整出现位置。
比如要匹配关键词python,使用bpythonb的正则模式,就不会匹配到python3、cpython这类包含python子串的内容。
完整代码实现
下面是包含不区分大小写匹配、边界定位、区间高亮的完整实现代码:
import re
def highlight_text(text, keyword, highlight_tag="span", highlight_style="color: red;"):
"""
实现不区分大小写的文本高亮,支持边界定位和区间高亮
:param text: 原始文本
:param keyword: 要高亮的关键词
:param highlight_tag: 高亮使用的HTML标签
:param highlight_style: 高亮标签的样式
:return: 高亮后的文本
"""
# 构造带单词边界的正则表达式,设置不区分大小写模式
pattern = re.compile(r'b' + re.escape(keyword) + r'b', re.IGNORECASE)
# 找到所有匹配的区间,返回的是(start, end)的列表
matches = list(pattern.finditer(text))
if not matches:
return text
result_parts = []
last_end = 0
# 遍历所有匹配区间,分段拼接结果
for match in matches:
start = match.start()
end = match.end()
# 添加匹配区间之前的内容
result_parts.append(text[last_end:start])
# 添加高亮后的匹配内容
matched_text = text[start:end]
result_parts.append(f'<{highlight_tag} style="{highlight_style}">{matched_text}</{highlight_tag}>')
last_end = end
# 添加最后一段剩余内容
result_parts.append(text[last_end:])
return ''.join(result_parts)
# 测试示例
if __name__ == "__main__":
original_text = "Python是一门流行的编程语言,python的应用场景很广,很多人学习Python,cpython是Python的参考实现。"
target_keyword = "python"
highlighted = highlight_text(original_text, target_keyword)
print(highlighted)
代码说明
代码中首先使用re.escape对关键词做转义,避免关键词中包含正则特殊字符导致匹配错误。然后通过re.compile构造正则对象,添加re.IGNORECASE标志实现不区分大小写匹配,同时使用b作为单词边界保证匹配的是完整关键词。
finditer方法会返回所有匹配的迭代器,每个匹配对象包含匹配的起始和结束位置,我们通过遍历这些位置,把原文分成匹配区间和非匹配区间,只给匹配区间的内容添加高亮标签,最终实现区间高亮的效果。
注意事项
- 如果不需要严格的单词边界匹配,可以去掉正则中的
b,此时会匹配所有包含关键词子串的内容。 - 高亮标签可以根据需求替换,比如换成
strong、em等语义化标签,样式也可以自定义调整。 - 如果原文中包含HTML特殊字符,需要在高亮前做对应的转义处理,避免破坏HTML结构。