Объединение запускается из python -docx с целью применения регулярного выражения к группе запусков - PullRequest
0 голосов
/ 08 мая 2020

Я использую Python -Docx для чтения файлов docx, поиска определенной строки (например, даты) и замены ее другой строкой (например, новой датой).

Вот два функции, которые я использую:

def docx_replace_regex(doc_obj, regex , replace):
for p in doc_obj.paragraphs:
    if regex.search(p.text):
        inline = p.runs
        # Loop added to work with runs (strings with same style)
        for i in range(len(inline)):
            if regex.search(inline[i].text):
                text = regex.sub(replace, inline[i].text)
                inline[i].text = text
for table in doc_obj.tables:
    for row in table.rows:
        for cell in row.cells:
            docx_replace_regex(cell, regex , replace)

def replace_date(folder,replaceDate,*date):
    docs = [y for x in os.walk(folder) for y in glob(os.path.join(x[0], '*.docx'))]
    for doc in docs:
        if date: #Date is optional date to replace
            regex = re.compile(r+date)
        else: #If no date provided, replace all dates
            regex = re.compile(r"(\w{3,12}\s\d{1,2}\,?\s?[0-9]{4})|((the\s)?\d{1,2}[th]{0,2}\sday\sof\s\w{3,12}\,\s?\d{4})")
        docObj = Document(doc)
        docx_replace_regex(docObj,regex,replaceDate)
        docObj.save(doc)

Первая функция - это, по сути, функция поиска и замены для использования python с файлом docx. Второй файл рекурсивно просматривает путь к файлу, чтобы найти файлы docx для поиска. Детали регулярного выражения не имеют отношения (я думаю). По сути, он ищет разные форматы даты. Он работает так, как я хочу, и не должен влиять на мою проблему.

Когда документ передается в docx_replace_regex, эта функция выполняет итерацию по абзацам, затем выполняет и ищет прогоны для моего регулярного выражения. Проблема в том, что прогоны иногда разбивают одну строку текста, поэтому, если do c был в виде открытого текста, регулярное выражение захватило бы текст, но поскольку прогоны разбивают текст, текст не захватывается.

Например, если мой абзац - «10 мая 2020 года», встроенный массив может быть ['1','0th day of May,',' 2020'].

Изначально я присоединился к встроенному массиву, чтобы он был равен до «10 мая 2020 года», но тогда я не могу заменить запуск новым текстом, потому что моя встроенная переменная является строкой, а не объектом запуска. Даже если бы я оставался встроенным в качестве объекта запуска, он все равно заменял бы только одну часть текста, который я ищу.

Ищу идеи, как правильно заменить часть текста, захваченную моим регулярным выражением. В качестве альтернативы, почему предложение разбивается на отдельные серии как есть.

1 Ответ

0 голосов
/ 08 мая 2020

Это непростая проблема, поскольку, похоже, вы начинаете понимать:)

Самый простой из возможных подход - поиск и замена в paragraph.text, например:

paragraph.text = my_replace_function(paragraph.text, ...)

Это работает, но все форматирование символов теряется. Более сложный подход находит смещение поисковой фразы, сопоставляет его с прогонами, а затем разделяет и повторно объединяет прогоны по мере необходимости, чтобы изменить только те прогоны, содержащие фразу поиска.

Похоже, здесь есть рабочее решение: { ссылка }, который показывает по длине, сколько задействовано.

Раньше оно появлялось довольно часто, поэтому, если вы выполните поиск здесь в SO на [python-docx] replace, вы узнайте больше о сути проблемы.

...