выделение слов в файле docx с использованием python-docx дает неверные результаты - PullRequest
0 голосов
/ 22 марта 2019

Я хотел бы выделить определенные слова в документе MS Word (здесь они представлены как негативный список) и оставить остальную часть документа, как это было раньше.Я пытался перенять этот один , но не могу запустить его так, как должен:

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):

ГЛАВА 1

Столетия назад здесь жили -

"Король!"мои маленькие читатели сразу скажут.

Нет, дети, вы ошибаетесь.Когда-то был кусок дерева.Это был не дорогой кусок дерева.Отнюдь не.Просто обычный кусок дров, один из тех толстых, твердых бревен, которые зимой поджигают, чтобы в холодных комнатах было уютно и тепло.

С моим кодом много проблем:

1) Первое предложение работает, но второе предложение в два раза.Почему?

2) Формат теряется в той части, где я выделяю.Возможно, мне понадобится скопировать свойства оригинального прогона во вновь созданные, но как мне это сделать?

3) Я теряю терминал "-"

4) ВВ последнем абзаце выделено, что «уютно и тепло» отсутствует ...

Что мне понадобится, так это более быстрое решение этих проблем, или, может быть, я обдумываю это, и есть намного более простой способ сделать выделение?(что-то вроде doc.highlight ({"king": "pink"}, но я ничего не нашел в документации)?

1 Ответ

2 голосов
/ 22 марта 2019

Вы не задумываетесь об этом, это сложная проблема;это форма проблемы поиска и замены.

Целевой текст может быть легко найден с помощью поиска Paragraph.text, но его замена (или, в вашем случае, добавление форматирования) при сохранении другого форматирования требует доступана уровне Run, оба из которых вы обнаружили.

Однако есть некоторые сложности, которые делают его сложным:

  • Гарантии нетчто ваша целевая строка "найти" находится целиком за один проход.Таким образом, вам нужно будет найти цикл, содержащий начало вашей целевой строки, и цикл, содержащий конец вашей целевой строки, а также любые промежуточные значения.

    Этому может помочь использование смещений символов, например, «Король» появляется при смещении символа 3 в «Король!»... 'и имеет длину 4, затем указывается, какой прогон содержит символ 3, а какой содержит символ (3 + 4).

  • Относительно первого осложнения нетГарантируйте, что все серии, в которых частично появляется целевая строка, отформатированы одинаково.Например, если вашей целевой строкой было « полужирное слово», обновленная версия (после добавления выделения) потребует не менее трех прогонов, один для «а», один для «полужирный ", и один для" слова "(кстати, каждый из двух пробельных символов в нем не изменится).

    Если вы примете упрощение, целевая строка всегда будетОдним словом, вы можете рассмотреть упрощение предоставления заменяющему прогону форматирования первого символа (первого прогона) найденных целевых прогонов, что, вероятно, является обычным подходом.

Итак, яПредположим, что есть несколько возможных подходов, но один из них должен был бы «нормализовать» прогоны каждого абзаца, содержащего целевую строку, так, чтобы целевая строка появилась в отдельном прогоне.Тогда вы можете просто применить подсветку к этому прогону и получить желаемый результат.

Чтобы получить дополнительную помощь, вам нужно сузить проблемные области и предоставить конкретные входные и выходные данные.Я бы начал с первого (возможно, потерял "-") (в отдельном вопросе, возможно, связанного отсюда), а затем продолжал бы один за другим, пока все не заработало.Он слишком много просит респондента подготовить свой собственный контрольный пример:)

Тогда у вас возникнет вопрос типа: «Я запускаю строку:« Столетия назад ... - »через этот код иТрейлинг "-" исчезает ... ", что намного проще для людей, чтобы их рассуждать.

Еще одним хорошим следующим шагом может быть распечатка текста каждого прогона, просто чтобы вы получили представление окак они расстались.Это может дать вам представление о том, где оно не работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...