#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)