使用pythondocx突出显示docx文件中的单词会导致错误的结果

2024-09-30 02:15:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我想突出显示MS-word文档中的特定单词(这里以否定列表的形式给出),并保留文档的其余部分。我试图从这个one中采用,但我无法让它正常运行:

from docx.enum.text import WD_COLOR_INDEX
from docx import Document
import pandas as pd
import copy
import re

doc = Document(docxFileName)

negativList = ["king", "children", "lived", "fire"]  # some examples

for paragraph in doc.paragraphs:
    for target in negativList:
        if target in paragraph.text:  # it is worth checking in detail ...

            currRuns = copy.copy(paragraph.runs)   # deep copy as we delete/clear the object
            paragraph.runs.clear()

            for run in currRuns:
                if target in run.text:
                    words = re.split('(\W)', run.text)  # split into words in order to be able to color only one
                    for word in words:
                        if word == target:
                            newRun = paragraph.add_run(word)
                            newRun.font.highlight_color = WD_COLOR_INDEX.PINK
                        else:
                            newRun = paragraph.add_run(word)
                            newRun.font.highlight_color = None
                else: # our target is not in it so we add it unchanged
                    paragraph.runs.append(run)

doc.save('output.docx')

例如,我使用以下文本(在word docx文件中):

CHAPTER 1

Centuries ago there lived --

"A king!" my little readers will say immediately.

No, children, you are mistaken. Once upon a time there was a piece of wood. It was not an expensive piece of wood. Far from it. Just a common block of firewood, one of those thick, solid logs that are put on the fire in winter to make cold rooms cozy and warm.

我的代码有多个问题:

1)第一句话行得通,但第二句是两句话。为什么?在

2)格式在我突出显示的部分丢失了。我可能需要将原始运行的属性复制到新创建的属性中,但是我如何做到这一点呢?在

3)我松开端子“-”

4)在突出显示的最后一段中,缺少“舒适和温暖”。。。在

我需要的是一个解决这些问题的方法,或者我想得太多了,有一个更简单的方法来突出显示?(有点像文档突出显示({“king”:“pink”}但是我在文档中没有找到任何东西?在


Tags: ofruntextin文档importtargetfor
2条回答

你们并没有想太多,这是一个具有挑战性的问题;这是一种搜索和替换问题。在

通过搜索Paragraph.text可以很容易地找到目标文本,但是替换它(或者在您的例子中添加格式)同时保留其他格式需要在Run级别进行访问,这两个都是您发现的。在

但也有一些复杂的问题,这就是它具有挑战性的原因:

  • 不能保证“find”目标字符串在一次运行中完全定位。因此,您需要找到包含目标字符串的开始的运行和包含目标字符串的结束的运行,以及两者之间的任何一个。在

    这可能有助于使用字符偏移量,例如“King”出现在“A King!”…“中的字符偏移量3处,且长度为4,然后确定哪个运行包含字符3,哪个包含字符(3+4)。

  • 与第一个复杂度相关,不能保证部分出现目标字符串的所有运行的格式都相同。例如,如果您的目标字符串是“a粗体word”,则更新后的版本(添加突出显示后)将至少需要三次运行,一次用于“a”,一次用于“bold”,一次用于“word”(顺便说一句,两个空格字符出现在中的运行方式不会改变它们的显示方式)。在

    如果接受目标字符串始终是单个单词的简化,则可以考虑简化为将找到的目标运行的第一个字符(第一个运行)的格式设置为替换运行,这可能是通常的方法。

所以我想有几种可能的方法,但是一种方法是“规范化”包含目标字符串的每个段落的行数,以便目标字符串出现在不同的行中。然后你就可以在那次跑步中应用高亮显示,你就会得到你想要的结果。在

为了提供更多帮助,您需要缩小问题区域并提供具体的输入和输出。我会从第一个问题开始(可能会丢失“”)(在一个单独的问题中,可能会从这里链接起来),然后一个接一个地进行,直到一切都成功为止。对于一个被调查者来说,提出自己的测试用例要求太高了:)

然后你会有这样一个问题:“我在操纵琴弦:‘几个世纪前……’通过这段代码,后面的“消失了…”,这对人们来说更容易理解。在

另一个好的下一步可能是打印出每次运行的文本,这样你就可以了解它们是如何分裂的。这可能会让你洞察它在哪里不起作用。在

我遇到了一个类似的问题,我应该在文档中突出显示一组单词。我修改了OP代码的某些部分,现在我可以正确地突出显示选中的单词。在

正如OP在评论中所说:paragraph.runs.clear()改为{}。 我在代码的以下部分添加了几行:

 else:
    paragraph.runs.append(run)

要得到这个:

^{pr2}$

在遍历currRuns时,我们提取run的文本内容并将其添加到段落中,因此需要再次突出显示这些单词。在

相关问题 更多 >

    热门问题