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

使用python-docx替换Word文本时如何保留原文本格式

问题原因

直接调用paragraph.text.replace()后赋值给paragraph.text会丢失原有格式,核心原因是Word文档中段落的字体、颜色、字号等样式属性是绑定在Run(文本块)对象上的,直接修改paragraph.text会清空段落下所有带格式的原有Run,自动生成一个使用默认样式的新Run存储文本,原有的样式自然全部丢失。
你找到的手动设置Run字体颜色的参考代码逻辑是可行的,但完全不需要手动重新给替换后的文本设置样式——只要在原有Run上做文本替换,Run本身的样式属性会完整保留,替换后的文本自动继承原格式。

可直接复用的适配方案

基础版(覆盖90%常规场景)

适用场景:待替换的目标词汇没有被拆分到多个文本块(即没有对词汇内的单个字符单独设置格式、没有Word自动拆分Run的情况),直接替换对应Run的文本即可,格式100%保留。
把你原有代码中直接修改paragraph.text的逻辑替换为遍历Run的逻辑即可:

from docx import Document

# 加载你的目标文档
doc = Document("你的文档路径.docx")
target_word = "example"
replace_word = "hello"

# 表格内文本替换
for table in doc.tables:
    for row in table.rows:
        for cell in row.cells:
            for paragraph in cell.paragraphs:
                # 遍历段落内所有带格式的文本块做替换
                for run in paragraph.runs:
                    if target_word in run.text:
                        run.text = run.text.replace(target_word, replace_word)

# 如果需要同时替换正文(非表格内)的对应词汇,保留这段,不需要可删除
for paragraph in doc.paragraphs:
    for run in paragraph.runs:
        if target_word in run.text:
            run.text = run.text.replace(target_word, replace_word)

doc.save("替换完成的文档.docx")

替换后的hello会自动继承原example所在文本块的所有样式,包括字体、颜色、字号、加粗、斜体、下划线等属性,不需要额外手动设置字体参数。

增强版(兼容目标词跨多个文本块的场景)

如果之前对目标词内的部分字符做过单独格式调整,Word会把一个词拆分到多个Run中存储,基础版会出现匹配不到的问题,用下面的封装函数即可处理:

from docx import Document

def replace_keep_format(paragraph, target, replacement):
    runs = paragraph.runs
    full_text = "".join([run.text for run in runs])
    if target not in full_text:
        return
    # 定位目标词在整段文本中的位置
    start_pos = full_text.find(target)
    end_pos = start_pos + len(target)
    # 建立字符到对应Run的映射
    char_to_run = []
    for run_idx, run in enumerate(runs):
        char_to_run.extend([(run_idx, char_idx) for char_idx in range(len(run.text))])
    # 定位目标词覆盖的首尾Run
    start_run_idx, start_char_idx = char_to_run[start_pos]
    end_run_idx, end_char_idx = char_to_run[end_pos - 1]
    # 替换文本写入起始Run,自动继承该Run的格式
    runs[start_run_idx].text = runs[start_run_idx].text[:start_char_idx] + replacement
    # 清空目标词覆盖的中间Run内容
    for run_idx in range(start_run_idx + 1, end_run_idx):
        runs[run_idx].text = ""
    # 处理尾Run剩余文本
    if start_run_idx != end_run_idx:
        runs[start_run_idx].text += runs[end_run_idx].text[end_char_idx + 1:]
        runs[end_run_idx].text = ""

# 调用示例
doc = Document("你的文档路径.docx")
# 处理表格内文本
for table in doc.tables:
    for row in table.rows:
        for cell in row.cells:
            for paragraph in cell.paragraphs:
                replace_keep_format(paragraph, "example", "hello")
# 如需处理正文加下面这段
for paragraph in doc.paragraphs:
    replace_keep_format(paragraph, "example", "hello")

doc.save("替换完成的文档.docx")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:58:01