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

Openpyxl适配中韩文本:多词匹配时高亮最长词的解决方案

解决非英文(中文/韩语)文本词汇高亮问题

问题根源

  • 原代码使用\b正则单词边界,该规则仅适用于英文这类以空格分隔单词的语言,中文、韩语属于连续字符体系,无明确单词边界,导致匹配失效。
  • 词汇列表未做排序处理,会出现短词优先匹配、长词被拆分的情况(比如示例中사과先匹配的话,사과파이会被拆分为사과+파이,无法完整匹配长词)。

修正后的完整代码

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_file1.xlsx", usecols=['word'])
prev_list = prev_words['word'].tolist()

# 按词汇长度降序排序,确保长词优先匹配,避免短词覆盖长词
prev_list_sorted = sorted(prev_list, key=lambda x: len(x), reverse=True)

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

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

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

for row in ws.iter_rows(min_row=1):
    for cell in row:
        if not cell.value: 
            continue    # 跳过空单元格
        msg = str(cell.value)
        matched_spans = set()  # 记录已匹配的位置,避免重复高亮

        # 遍历排序后的词汇,逐个匹配
        for word in prev_list_sorted:
            # 移除\b,直接匹配词汇本身,同时转义特殊字符
            pattern = re.compile(re.escape(word))
            for match in pattern.finditer(msg):
                start, end = match.span()
                # 检查当前匹配区间是否和已有的重叠,不重叠才加入
                overlap = False
                for s, e in matched_spans:
                    if not (end <= s or start >= e):
                        overlap = True
                        break
                if not overlap:
                    matched_spans.add((start, end))

        # 将匹配的区间按起始位置排序
        red_spans = sorted(matched_spans)
        if not red_spans: 
            continue    # 无匹配内容则跳过

        # 构建富文本
        rich_text = CellRichText()
        prev_pos = 0        # 上一个高亮区间的结束位置
        for left, right in red_spans:
            if prev_pos < left:
                rich_text.append(TextBlock(black, msg[prev_pos:left]))
            rich_text.append(TextBlock(red, msg[left:right]))
            prev_pos = right
        if prev_pos < len(msg):
            rich_text.append(TextBlock(black, msg[prev_pos:]))
        cell.value = rich_text       

wb.save("result1.xlsx")

关键修改点

  • 移除\b正则边界:直接匹配词汇本身,适配中文、韩语等连续字符语言的文本结构。
  • 词汇按长度降序排序:优先匹配长词汇,彻底解决短词覆盖长词的问题(比如示例中先匹配사과파이,再匹配사과)。
  • 新增已匹配位置去重逻辑:避免同一字符区间被多次匹配,确保高亮区间不重叠。
  • 使用re.escape()处理特殊字符:如果词汇中包含正则语法符号(如.*+?等),会自动转义,避免匹配逻辑异常。

内容的提问来源于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 12:42:32