Извлечение текста между любой комбинацией выражений (список) - PullRequest
0 голосов
/ 05 ноября 2018

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

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

sample_text = """Some random text 
asdasd
asdasd
asdasd
**Dear my friend,
this is the text I want to extract.
Sincerly,
David**
some other random text
adasdsasd"""

Пока мой код:

letter_begin = ["dear", "to our", "estimated", ...]
letter_end = ["sincerly", "yours", "best regards", ...]

with open('path/to/input') as infile, open('path/to/output', 'w') as outfile:
    copy = False
    for line in infile:
        if line.strip() == "dear": #shortcomming: only 1 Expression possible here
            copy = True
        elif line.strip() == "sincerly": #shortcomming: only 1 Expression possible here
            copy = False
        elif copy:
            outfile.write(line)

Приведенный выше пример включает в себя «Dear» как выражение letter_begin и «Sincerly» как выражение letter_end. Мне нужно иметь гибкий код, который может перехватывать любое начальное и конечное буквенное выражение из приведенных выше списков (любую возможную комбинацию выражений; например, «Уважаемые [...] rest regards» или «Estimated [...]» Sincerly ")

1 Ответ

0 голосов
/ 05 ноября 2018

Мы можем попробовать использовать re.findall в многоточечном и многострочном режиме, используя следующий шаблон:

Dear\s+.*?Sincerely,\n\S+

Это будет охватывать и включать в себя все, начиная от слова Dear, вплоть до Sincerely, за которым следует все, что следует за следующей строкой после Sincerely. Вот пример кода:

output = re.findall(r"Dear\s+.*?Sincerely,\n\S+", sample_text, re.MULTILINE|re.DOTALL)
print(output)

Edit:

Если вы хотите сопоставить несколько возможных приветствий и закрытий, то мы можем использовать чередование:

letter_begin = ["dear", "to our", "estimated"]
openings = '|'.join(letter_begin)
print(openings)
letter_end = ["sincerely", "yours", "best regards"]
closings = '|'.join(letter_end)
regex = r"(?:" + openings + r")\s+.*?" + r"(?:" + closings + r"),\n\S+"
output = re.findall(regex, sample_text, re.MULTILINE|re.DOTALL|re.IGNORECASE)
print(output)

['Dear my friend,\nthis is the text I want to extract.\nSincerely,\nDavid**']
...