Регулярное выражение для поиска текста в нескольких строках

#python #regex #multiline

Вопрос:

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

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

 print(match.group(1).strip())
AttributeError: 'NoneType' object has no attribute 'group'
 

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

Любая помощь была бы отличной, спасибо!

 import fitz
import re

doc = fitz.open(r'file.pdf')
text_list = [ ]
for page in doc:
    text_list.append(page.getText())
    #print(text_list[-1])
text_string = ' '.join(text_list)
test_string = "Observations of Client Behavior: THIS IS THE DESIRED TEXT. Observations of Client's response to skill acquisition" #works for this test
pat = r".*?Observations of Client Behavior: (.*) Observations of Client's response to skill acquisition*"

match = re.search(pat, text_string)
print(match.group(1).strip())
 

Когда я выполняю поиск по фразам, которые находятся в одной строке в длинном текстовом файле, это работает. Но как только они оказываются на разных линиях, это больше не работает.

Вот пример входного текста, который вызывает у меня проблему:

 Observations of Client Behavior: Overall interfering behavior data trends are as followed: Aggression frequency 
has been low and stable at 0 occurrences for the past two consecutive sessions. Elopement frequency is on an 
overall decreasing trend. Property destruction frequency is on an overall decreasing trend. Non-compliance 
frequency has been stagnant at 2 occurrences for the past two consecutive sessions, but overall on a 
decreasing trend. Tantrum duration data are variable; data were at 89 minutes on 9/27/21, but have starkly 
decreased to 0 minutes for the past two consecutive sessions. Observations of Client's response to skill 
acquisition: Overall skill acquisition data trends are as followed: Frequency of excessive mands 
 

Комментарии:

1. В коде у вас есть текст «Наблюдения за реакцией клиента на приобретение навыков» после «ЭТО ЖЕЛАЕМЫЙ ТЕКСТ». таким образом, ваш шаблон может соответствовать этому, но в вашем примере ввода у вас нет «Наблюдений за реакцией клиента на приобретение навыков» после «Частота агрессии», это причина ошибки. Также вы можете проверить свое регулярное выражение здесь

2. @Alireza это была ошибка копирования/вставки с моей стороны, извините! Я отредактировал код, чтобы точно отразить то, что у меня есть

3. @Alireza Здесь — когда я вставляю разрыв строки в тестовый случай, он больше не работает regex101.com/r/EDb77r/1

4. Чего именно вы хотите от этого ввода? текст после «Наблюдения за поведением клиента:»?

5. @alizera да. После этого и до строки о приобретении навыков. между ними должно быть 3-4 предложения

Ответ №1:

Обратите внимание, что . соответствует любому символу, отличному от новой строки. Так что вы могли бы использовать (.|n) , чтобы запечатлеть все. Кроме того, кажется, что линия может оборваться внутри вашего фиксированного шаблона. сначала определите префикс и суффикс шаблона:

 prefix=r"Observationss ofs Clients Behavior:"
sufix=r"Observationss ofs Client'ss responses tos skills acquisition:"
 

а затем создайте шаблон и найдите все вхождения:

 pattern=prefix r"((?:.|n)*?)" suffix
f=re.findall(pattern,text_string)
 

Используя *? в конце r"((?:.|n)*?)" мы сопоставляем как можно меньше символов.

Пример многострочного мульти-шаблона:

 text_string = '''any thing Observations of Client Behavior: patern1 Observations of Client's 
response to skill acquisition: any thing
any thing Observations of Client Behavior: patern2 Observations of 
Client's response to skill acquisition: any thing Observations of Client
Behavior: patern3 Observations of Client's response to skill acquisition: any thing any thing'''

result=re.findall(pattern,text_string)
 

результат=[‘ patern1 ‘, ‘ patern2 ‘, ‘ patern3 ‘]

проверьте результат здесь

Комментарии:

1. Абсолютно идеально, спасибо!