В чем суть "?=" в регулярном выражении

Есть регулярное выражение для пароля:

/^[A-Z](?=.*[0-9])(?=.*[!@#$%^&*])(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z!@#$%^&*]{8,}/

Его суть я понимаю.

  1. (?=^[A-Z]) - первый символ пароля имеет верхний регистр
  2. (?=.*[0-9]) - строка содержит хотя бы одно число;
  3. (?=.[!@#$%^&]) - строка содержит хотя бы один спецсимвол;
  4. (?=.*[a-z]) - строка содержит хотя бы одну латинскую букву в нижнем регистре;
  5. (?=.*[A-Z]) - строка содержит хотя бы одну латинскую букву в верхнем регистре;
  6. [0-9a-zA-Z!@#$%^&*]{8,} - строка состоит не менее, чем из 8 вышеупомянутых символов.

Но не могу разобраться для чего тут ?= и что оно означает.


Ответы (3 шт):

Автор решения: Павел

?= - это так называемое "заглядывание вперёд" (lookahead assertion).

Существует несколько типов такого "заглядывания":

  1. Заглядывание вперед: foo(?=bar), совпадёт foo только перед bar, при этом сама строка bar не войдет в найденный текст.
  2. Отрицательное заглядывание вперед: foo(?!bar), совпадет foo, только если после этой строки не следует bar.
  3. Ретроспективная проверка: (?<=foo)bar, совпадет bar только после foo, при этом сама строка foo не войдет в найденный текст.
  4. Отрицательное заглядывание назад: foo(?<!bar), совпадет bar, только если перед этой строкой нет foo.

Источник примеров

Конкретно в вашем случае этот прием используется для того, чтобы объединить группы поиска отдельных частей пароля в одну общую сущность, предшествующая часть совпадёт, только в случае если после неё следует то, что указано после ?=

→ Ссылка
Автор решения: SergFSM

эта регулярка работает так:

  • первая буква пароля - заглавная латинская
  • она должна стоять перед цифрой (первое (?=...))
  • также она должна стоять перед символом из указанного списка (второе (?=...))
  • также она должна стоять перед малой латинской (третье (?=...))
  • также она должна стоять перед еще одной заглавной латинской (четвертое (?=...))
  • после нее должны стоять минимум восемь знаков из указанного списка

итого, пароль должен начинаться на заглавную латинскую букву и должен состоять не менее чем из 9 знаков, в том числе, цифр, малых и больших латинских и символов.

→ Ссылка
Автор решения: ipatev_nn

Знак вопроса ? самостоятельно является квантификатором 0 или 1 совпадение предыдущего шаблона, а равно = не является метасимволом вовсе.

Только находясь в круглых скобках (?=...) они начинают работать как позитивный просмотр вперед.
Группа позитивного просмотра вперед отличается от обычной группы, тем что не захватывает данные, а устанавливает курсор:

Возьмем строку:
abcd1f
И регулярное выражение:
.(?=[0-9])
Точка в регулярных выражениях это любой символ(за некоторыми исключениями)

abcd1f
___^___ результатом захвата будет буква d перед цифрой 1

Если использовать обычную группу .([0-9])

abcd1f
___^^__ результатом захвата будет буква d и цифра 1
____^__ так же будет захвачена цифра 1 в группу 1

Как ранее уже говорили, что группы существуют нескольких типов:
(?=...) - позитивный просмотр вперед
(?!...) - негативный просмотр вперед
(?<=...) - позитивный просмотр назад
(?<!...) - негативный просмотр назад

на примере из работы:

fs4a
_^___ .(?=[0-9]) - захватит s
___^_ (?<=[0-9]). - захватит a
^_^^_ .(?![0-9]) - захватит f,4,a
^^^__ (?<![0-9]). - захватит f,s,4
→ Ссылка