Выдача строки замены Regex - PullRequest
0 голосов
/ 15 марта 2020

Я пытаюсь сделать текст в виде нижеприведенной текстовой переменной print as:

"" "Глава # Заголовок главы

ВВЕДЕНИЕ

Вверх качественный текст ... "" "

вместо этого я получаю:

" "" Глава # Заголовок главы

X

... "" "

Я даже не могу понять ошибку. Откуда даже Х приходит? Это не имеет смысла, поэтому я не знаю, какую проблему мне нужно решить. Кто-нибудь знает, в чем проблема?

import re

text = """
...Garbage text prior to start

INTRODUCTION

Top quality text...
"""

file_name = 'Chapter # Chapter title'

def clip_beginning(text):
    '''Removes all text prior to the keyword'''
    beginning_phrase_list = ['INTRODUCTION', 'Starting section 2']
    processed_text = re.sub(rf'(.|\n)*{beginning_phrase_list}', rf'{file_name}\n\1\n', text)
    return processed_text

text = clip_beginning(text)

print(text)

Ответы [ 2 ]

1 голос
/ 15 марта 2020

Это то, к чему вы стремитесь? Проблема не в использовании rf.

решение

>>> text = '\n...Garbage text prior to start\n\nINTRODUCTION\n\nTop quality text...\n'
>>> 
>>> beginning_phrase_list = ['INTRODUCTION', 'Starting section 2']
>>> 
>>> file_name = 'Chapter # Chapter title'
>>> 
>>> result = re.sub(rf"^.*?({'|'.join(beginning_phrase_list)})", 
...                 rf"{file_name}\n\n\1", text, flags=re.DOTALL)
>>> 
>>> print(result)
Chapter # Chapter title

INTRODUCTION

Top quality text...

>>> # The expression, when evaluated becomes... 
>>>
>>> becomes = rf"^.*?({'|'.join(beginning_phrase_list)})"
>>> becomes
'^.*?(INTRODUCTION|Starting section 2)'
>>>

Вы использовали группировку в своем выражении, которая соответствовала мусору, а затем помещала его в строке подстановки с \1. Я изменил группировку, чтобы соответствовать списку фраз. И обновил выражение совпадения списка фраз, чтобы оно было объединено в OR.

flags=re.DOTALL говорит re.sub() сопоставлять символы новой строки с точкой ..

Символ каретки, ^, указывает re.sub() начинать сопоставление с начала строки - это гарантирует, что весь мусор будет захвачен.

Использование rf в совпадениях регулярного выражения и подстановке в порядке, и фактически это делает для некоторых очень элегантных решений для сопоставления и замены операций.

таинственный X

>>> # The way it was before...
>>>
>>> evaluates_to = rf'(.|\n)*{beginning_phrase_list}'
>>> evaluates_to
"(.|\\n)*['INTRODUCTION', 'Starting section 2']"

Ваше выражение было эквивалентно:

"(.|\\n)*[ ',2CDINORSTUaceginorst]"

Обратите внимание на набор совпадений [...]. Поместив переменную beginning_phrase_list в выражение raw, вы создали набор совпадений из-за квадратных скобок, которые есть в списке при строковом преобразовании.

Вот как я преобразовал его в этот странно выглядящий набор:

>>> match_set = list( set( str(beginning_phrase_list)[1:-1] ) )
>>> match_set.sort()
>>>
>>> '[' + ''.join(match_set) + ']'
"[ ',2CDINORSTUaceginorst]"

То, что будет делать это выражение "(.|\\n)*[ ',2CDINORSTUaceginorst]", будет искать последний символ в целевой строке, который соответствует набору совпадений. Что является последним t в его конце: xt...\n.

Этому последнему t предшествует x, которое захватывает группа захвата, (.|\n). Скобки создают группу захвата. x - это то, на что обратная ссылка \1 ссылается в вашей строке подстановки, rf'{file_name}\n\1\n'.

Группа захвата и звездочка (.|n)* создают группу захвата только для одного символа, поскольку звездочка не находится внутри выражения в скобках. Только одно выражение соответствует каждому символу, предшествующему последнему t, но только последний из них включается в группу захвата.

И X пишется с большой буквы, потому что .. потому что вы пишут его с большой буквы. На самом деле он выглядит как «х» в выводе.

И вот он у вас ... больше анализа, чем вы, вероятно, ожидали =)

0 голосов
/ 15 марта 2020

Изменить ...

processed_text = re.sub(rf'(.|\n)*{beginning_phrase_list}', rf'{file_name}\n\1\n', text)

На ...

processed_text = re.sub(r'(.|\n)*{beginning_phrase_list}', f'{file_name}\n\1\n', text)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...