Регулярное выражение Python не соответствует, когда regex101 показывает иначе

#python-3.x #regex

#python-3.x #регулярное выражение

Вопрос:

Я пытаюсь соответствовать следующему шаблону:

...hello world...foo...bar... где «.» может быть любым символом. Кроме того, оно не должно содержать слов alice и bob .

Это то, что я пробовал: pattern = r'^(?!.*(alice|bob)).*hello world.*foo.*bar' и я протестировал это на regex101.com и это работает, но когда я попробовал re.findall(pattern, "hello world, this is foo and bar") , оно не показывает соответствия.

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

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

1. Можете ли вы дать ссылку, показывающую, как это работает в regex101? regex101.com/r/T6URgt/1 Это то, что я вижу.

2. @axe319 извините, в моем первоначальном вопросе был тип .* hello world, а не *.hello world, обновлено только сейчас

3. @axe319 regex101.com/r/T6URgt/2

4. Попробуйте заключить свой шаблон в круглые скобки. regex101.com/r/T6URgt/3

5. Спасибо, кажется, теперь это работает! Есть идеи, почему оно ведет себя таким образом?

Ответ №1:

re.findall либо возвращает список всех групп захвата, если таковые имеются. Если нет, то возвращается полное совпадение.

В вашем примере (alice|bob) это группа захвата, даже если она находится в пределах негативного прогноза. Вот почему оно возвращает list с пустой строкой. Добавление круглых скобок вокруг всего шаблона делает его вашей первой группой захвата. И, следовательно, вернется в качестве первого элемента в вашем списке.

Существуют альтернативные способы обойти это. Вы могли бы удалить свою (alice|bob) группу захвата и заменить ее на .*alice|.*bob) , что является тем же самым, что и без группы захвата.

Полный код:

 import re

pattern = r'^(?!.*alice|.*bob).*hello world.*foo.*bar'
print(re.findall(pattern, 'hello world, this is foo and bar'))
  

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

1. Также существует группа, не захватывающая : (?:alice|bob)