У меня есть куча цитат, извлеченных из Goodreads, хранящихся на bs4.element.ResultSet, с каждым элементом типа bs4.element.Tag. Я пытаюсь использовать регулярное выражение с модулем re в python 3.6.3, чтобы очистить кавычки и получить только текст. Когда я повторяю и печатаю с помощью [print(q.text) for q in quotes], некоторые цитаты выглядят так:
“Don't cry because it's over, smile because it happened.”
―
а другие выглядят так:
“If you want to know what a man's like, take a good look at how he treats his inferiors, not his equals.”
―
,
У каждого также есть несколько дополнительных пустых строк в конце. Я думал, что могу перебирать quotes и вызывать re.match для каждой цитаты следующим образом:
cleaned_quotes = []
for q in quote:
match = re.match(r'“[A-Z].+$”', str(q))
cleaned_quotes.append(match.group())
Я предполагаю, что мой шаблон регулярного выражения ничего не соответствует, потому что я получаю следующую ошибку:
AttributeError: 'NoneType' object has no attribute 'group'
Неудивительно, что распечатка списка дает мне список объектов None. Есть идеи, что я делаю неправильно?
Две причины: во-первых, я все еще учусь и хочу попрактиковаться в использовании регулярных выражений. Во-вторых, мне пришлось использовать q.strip () и q.replace ('-', ''), чтобы избавиться от дефисов, и я надеялся, что регулярное выражение позволит мне получить только текст цитаты в одной строке.
Что ж, избавиться от '-' и завершающих пробелов кажется проще, чем с регулярным выражением для случайного предложения ...
Могу я просто сопоставить кавычки в начале и конце каждой цитаты и покончить с этим? Похоже, что теоретически это должно быть довольно быстро.






Прежде всего, в вашем выражении r'“[A-Z].+$”' конец строки $ определен до ", что логически невозможно.
Чтобы использовать $ в регулярном выражении для многострочных строк, вы также должны указать флаг re.MULTILINE.
Во-вторых, re.match ожидает совпадения всего значения, а не найдет часть строки, которая соответствует регулярному выражению.
Это означает, что re.search должен делать то, чего вы изначально ожидали.
Таким образом, результирующее регулярное выражение может быть:
re.search(r'"[A-Z].+"$', str(q), re.MULTILINE)
Это не сработает при наличии завершающих пробелов или знака «-» в конце цитаты.
Как вы просили об этом в учебных целях, вот ответ регулярного выражения:
(?<=“)[\s\s]+?(?=”)
Объяснение:
Мы используем позитивный взгляд назад и взгляд вперед, чтобы отметить начало и конец шаблона и одновременно удалить кавычки из результата.
Внутри цитат мы лениво сопоставляем что-либо с .+?
Образец кода:
import re
regex = r"(?<=“)[\s\S]+?(?=”)"
cleaned_quotes = []
for q in quote:
m = re.search(regex, str(q))
if m:
cleaned_quotes.append(m.group())
Возможно, нам не нужны никакие флаги регулярных выражений. Добавьте глобальный флаг g | для нескольких совпадений. И m | многострочный для обработки совпадений построчно (в таком сценарии может потребоваться использовать [\s\S] вместо точки для получения результатов с охватом строк).
Это также изменит поведение позиционных якоря^ и $, чтобы они соответствовали концу строки вместо строки. Следовательно, добавление этих позиционных якорей между ними просто неправильно.
Еще одна вещь, я использую re.search(), так как re.match() соответствует только с начала строки. Обычная ошибка. См. документация.
Впечатляет, +1 для просмотра вперед / назад
Это сработало отлично и было очень познавательно. Спасибо! И я понимаю, почему я должен был сопоставить [\ s \ S] +, а не просто. +
@ wp78de принято. У меня меньше 15 репутации, так что я пока не могу проголосовать за хаха.
@PrratekRamchandani исправлено :)
почему бы просто не удалить конечные пробелы с помощью
q.strip()?