Python-docx用replace丢失样式解决方案2_优化

首先感谢 艾派森 老师的 Python操作word基础 。

感谢 GIS开发者 老师的 使用python-docx实现对word文档里的字符串、图片批量替换

我曾将尝试将整个段落paragraph的runs合并成1个run,再进行替换,方案可行。也可以清除runs的内容,将最后一个run替换成修改后的数据,方案可行。不过缺点是同一个段落的样式都会按照最后一个文字块run的样式来,为了保留同一个段落的不同样式,我学习了  GIS开发者 老师的 使用python-docx实现对word文档里的字符串、图片批量替换 ,解决了样式问题,但出现了匹配问题,比如这种情况  “{2}月{ ”,会导致后一个匹配项匹配不到。

我根据我的理解进行了优化。

模板如下:

替换后的新文档如下:

代码如下:

# pip install python-docx
from docx import Document
import re
def write(path_template, path_new, dic_old_new, start_mark='{', end_mark='}'):
    # 将所有需要替换的数据存入一个集合,备用
    olds = set(dic_old_new.keys())
    # 打开文档
    doc1 = Document(path_template)
    # 读取里面的数据
    for p in doc1.paragraphs:
        # 检测本段是否有需要替换的数据
        olds_temp = set()
        for old in olds:
            if old in p.text:
                olds_temp.add(old)
        if len(olds_temp) == 0:
            continue

        # 检测本段的run,将包含old的run拼接,替换。
        merge_mark = False
        tmp = ''
        runs = p.runs
        for i, run in enumerate(runs):
            t = run.text
            # 开始标志'{'如果在本run中,启动拼接
            if start_mark in t:
                merge_mark = True
            # 拼接run内容,同时清除当前run内容,直到发现结束标志'}'
            if merge_mark is True:
                tmp += t
                run.text = ''
            # 结束标志'}'如果在本run中,结束拼接,开始替换
            if end_mark in t:
                merge_mark = False
                # 提取tmp需替换的部分
                lis_old_this = re.findall(f'{start_mark}.+?{end_mark}', tmp)
                # 如果出现{2}月{ 情况,则将{之后的部分提取,放入下一个tmp中,同时merge_mark = True。
                lis_start_mark = re.findall(start_mark, tmp)
                if len(lis_old_this) < len(lis_start_mark):
                    tmp_end = start_mark + tmp.split(start_mark)[-1]
                    tmp2 = tmp[:-len(tmp_end)]
                    tmp = tmp_end
                    merge_mark = True
                else:
                    tmp2 = tmp
                    tmp = ''
                # 替换
                for old_this in lis_old_this:
                    if old_this in olds_temp:
                        new = dic_old_new[old_this]
                        tmp2 = tmp2.replace(old_this, new)
                # 将目前的run内容替换成tep2
                run.text = run.text.replace(run.text, tmp2)
    # 保存新文件
    doc1.save(path_new)

if __name__ == '__main__':
    dic_old_new = {'{0}': '00001', '{1}': '2030', '{2}': '01', '{3}': '01',
        '{4}': '01', '{5}': '01', '{6}': '闯红灯', '{7}': '600'}
    write('template.docx', 'new.docx', dic_old_new)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值