Какова цель .* в регулярном выражении Python с опережением?

Я изучаю регулярные выражения и нашел интересную и полезную страницу об их использовании для проверки ввода пароля здесь. У меня есть вопрос о .* в следующем выражении:

"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$"

Я понимаю, что .* — это подстановочный знак, представляющий любое количество текста (или отсутствие текста), но у меня возникли проблемы с пониманием его назначения в этих опережающих выражениях. Почему они необходимы для того, чтобы эти прогнозы функционировали должным образом?


person James S    schedule 04.08.2017    source источник
comment
Что в конце концов вы найдете [a-z] и т. д.   -  person Willem Van Onsem    schedule 04.08.2017
comment
@WillemVanOnsem да, но .* жадный. Точка не разрывает строку. Так может быть, они ищут разрыв строки, за которым следует какой-либо альфа-символ?   -  person Jerinaw    schedule 04.08.2017
comment
@Jerinaw: для просмотра вперед и т. д. нет фактора жадности, поскольку он не захватывает. Обычно разрыв строки не включается в точку ..   -  person Willem Van Onsem    schedule 04.08.2017


Ответы (1)


Упреждающий просмотр означает прямой просмотр вперед. Итак, если вы пишете:

(?=a)

это означает, что первый символ должен быть a. Иногда, например, при проверке пароля, вам это не нужно. Вы хотите сказать, что где-то должно быть a. Так:

(?=.*a)

означает, что первый символ может быть, например, b, 8 или @. Но что в конце концов где-то должно быть a.

Таким образом, ваше регулярное выражение означает:

^               # start a match at the beginning of the string
(?=.*[a-z])     # should contain at least one a-z character
(?=.*[A-Z])     # should contain at least one A-Z character
(?=.*\d)        # should contain at least one digit
[a-zA-Z\d]{8,}  # consists out of 8 or more characters and only A-Za-z0-9
$               # end the match at the end of the string

Без .* совпадений быть не могло, поскольку:

 "^(?=[a-z])(?=[A-Z])(?=\d)[a-zA-Z\d]{8,}$"

означает:

^               # start a match at the beginning of the string
(?=[a-z])       # first character should be an a-z character
(?=[A-Z])       # first character should be an A-Z character
(?=\d)          # first character should be a digit
[a-zA-Z\d]{8,}  # consists out of 8 or more characters and only A-Za-z0-9
$               # end the match at the end of the string

Поскольку нет символа, который одновременно является символом A-Z и цифрой. Это никогда не будет удовлетворено.

Боковые примечания:

  1. мы не захватываем упреждение, поэтому жадность не имеет значения;
  2. точка . по умолчанию не соответствует символу новой строки;
  3. даже если это так, тот факт, что у вас есть ограничение ^[A-Za-z0-9]{8,}$, означает, что вы только проверяете ввод без новой строки.
person Willem Van Onsem    schedule 04.08.2017