Использование re.findall () для поиска текста по нескольким критериям [python3 .8] - PullRequest
0 голосов
/ 10 июля 2020

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

Дальнейшее редактирование отметить, что:

  1. Связанный вопрос в заключительном уведомлении никоим образом не помогает мне с моей проблемой, и на самом деле зашел так далеко, что еще больше запутал меня обилие критериев и синтаксиса
  2. Я нашел решение проблемы здесь и поделюсь им в качестве ответа на повторное открытие этого вопроса, чтобы у всех, у кого возникла такая же проблема, была хотя бы отправная точка, если не Решение этой проблемы.

Ситуация:

Я написал программу, которая использует модуль запросов для захвата всего текста с веб-сайта, учитывая, что я использую тот же код для системы, которая действительно работает, эта часть не является проблемой. Я пытаюсь использовать re.findall() для получения данных в том порядке, в котором они появляются. В работающей системе я использую строку

paragraphs = re.findall(r'c1(.*?)c1', str(mytext))

, где c1 стоит вместо моего первого набора критериев Затем я использую несколько строк для избавиться от того, что мне не нужно.

Что я пробовал:

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

Первая попытка:

I попробовал просто сохранить его в строке

re.findall(r'c1(.*?)c1c2(.*?)c2', str(mytext))

, где c2 стоит вместо моего второго критерия К сожалению, это возвращает [], что бесполезно для меня.

Вторая попытка:

Я подумал, что, возможно, я сделал это неправильно, поэтому я немного перетасовал его

re.findall(r'c1(.*?)c1', r'c2(.*?)c2', str(mytext))

re.findall(r'c1(.*?)c1'r'c2(.*?)c2', str(mytext))

re.findall(r'c1(.*?)c1' or 'c2(.*?)c2', str(mytext))

re.findall(r'c1(.*?)c1' or r'c2(.*?)c2', str(mytext))

Но в случай первых двух, такой же, как моя первая попытка. Последние два получили только c1(.*?)c1, что является полезными данными, но оно не содержит c2(.*?)c2 вообще, не говоря уже о том, в каком порядке они появляются в тексте .

Третья попытка:

Не запускайте этот код это разбило мой ноутбук с бесконечным l oop. К этому моменту я провел некоторое исследование и обнаружил функцию re.search()

paragraphs = []
ticker = ''
while ticker != 'None':
    ticker = re.search(r'c1(.*?)c1', str(mytext))
    if (ticker == 'None'):
        ticker = re.search(r'c2(.*?)c2', str(mytext))
    if (ticker != 'None'):
        paragraphs.append(ticker)
print(paragraphs)

Очевидно, это была глупая идея. Он пытался заставить paragraphs[] иметь бесконечный список первых c1(.*?)c1.

Вопрос:

Как, если вообще, использовать re.findall() чтобы создать список paragraphs, который будет go через текст в mytext и выбрать все, что соответствует критериям c1(.*?)c1 и c2(.*?)c2, и поместить их в порядке их появления?

например, если текст (пробелы добавлены для ясности, в файле не будет)

c2 hello c2 c1 world c1 c2 !!! c2

Программа будет

#get the text
#do the re.findall() function and assign to the list paragraphs
print(paragraphs)

и вернет

>>>['hello', 'world', '!!!']

1 Ответ

0 голосов
/ 10 июля 2020

Вы можете использовать

[x.group(2) for x in re.finditer(r'(c1|c2)(.*?)\1', mytext, flags=re.S)]

См. Демонстрацию regex . Или, чтобы сопоставить самые короткие подстроки:

[x.group(2) for x in re.finditer(r'(c1|c2)((?:(?!c1|c2).)*?)\1', mytext, flags=re.S)]

Регулярное выражение соответствует

  • (c1|c2) - Группа 1: c1 или c2
  • (.*?) - Группа 2: любые 0 или более символов как можно меньше
  • \1 - то же значение, что и в группе 1.

for x in re.finditer(r'(c1|c2)(.*?)\1', mytext) выполняет итерацию по всем совпадениям и x.group(2) вернет только значения группы 2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...