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

Openpyxl列表词汇文字变色修复:仅最后匹配词变色问题

问题:Excel单元格批量标记指定词汇为红色时仅最后一个词汇生效

需求与问题

需要将Excel单元格文本中属于prev_list列表内的所有词汇设置为红色,但当前代码仅能将最后一个匹配的词汇改为红色。

示例

原句:

I have a dog, a cat and a fish

期望效果(匹配词汇显示为红色):

I have a dog(红色), a cat(红色) and a fish(红色)

实际效果:

I have a dog, a cat and a fish(红色)

错误原因分析

  1. 变量作用域问题:外层循环检查是否存在匹配词汇时,word变量最终会停留在prev_list中最后一个匹配的词汇,导致后续re.finditer仅针对该词汇进行查找,忽略了前面的匹配项。
  2. 富文本构建逻辑错误:每次找到匹配项时,都直接将整个文本拆分为「前缀+红词+后缀」添加到rich_text中,多次循环后会重复叠加文本,最终只有最后一次的修改覆盖显示。
  3. 未遍历所有目标词汇:没有对prev_list中的所有词汇进行全局匹配,仅处理了最后一个匹配的词汇。

修正后的代码

from openpyxl import Workbook
from openpyxl.cell.text import InlineFont
from openpyxl.cell.rich_text import TextBlock, CellRichText
import pandas as pd
from openpyxl.utils.dataframe import dataframe_to_rows
import re

# 读取目标词汇列表
prev_words = pd.read_excel("prev_file.xlsx", usecols=['word'])
prev_list = prev_words['word'].tolist()
# 构建正则表达式,匹配所有目标词汇(用\b避免部分匹配)
pattern = re.compile(r'\b(' + '|'.join(re.escape(word) for word in prev_list) + r')\b')

wb = Workbook()
ws = wb.active
df = pd.read_excel("new_file.xlsx")

# 将DataFrame写入工作表
for r in dataframe_to_rows(df, index=False, header=True):
    ws.append(r)

red = InlineFont(color='00FF0000')
black = InlineFont(color='00000000')

# 遍历所有行(min_row=1跳过表头,根据需求调整)
for row in ws.iter_rows(min_row=1):
    for cell in row:
        if cell.value is None:
            continue
        cell_value = str(cell.value)
        rich_text = CellRichText()
        last_end = 0
        
        # 查找所有匹配的目标词汇
        for match in pattern.finditer(cell_value):
            start_idx = match.start()
            end_idx = match.end()
            # 添加匹配前的普通文本
            if start_idx > last_end:
                rich_text.append(TextBlock(black, cell_value[last_end:start_idx]))
            # 添加红色的匹配词汇
            rich_text.append(TextBlock(red, cell_value[start_idx:end_idx]))
            last_end = end_idx
        
        # 添加最后一段普通文本
        if last_end < len(cell_value):
            rich_text.append(TextBlock(black, cell_value[last_end:]))
        
        # 无匹配时直接添加原文本
        if not rich_text:
            rich_text.append(TextBlock(black, cell_value))
        
        cell.value = rich_text

wb.save("resultresult2.xlsx")
wb.close()

关键修改点

  • 用正则表达式一次性匹配所有目标词汇,避免逐个词汇处理的遗漏问题
  • 按文本顺序逐步构建富文本,记录上一次匹配的结束位置,确保片段不重复、不遗漏
  • 添加空值判断,避免None值报错
  • 使用\b单词边界,避免把"doggy"这类词中的"dog"误标记

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 21:55:00