В чем суть "?=" в регулярном выражении
Есть регулярное выражение для пароля:
/^[A-Z](?=.*[0-9])(?=.*[!@#$%^&*])(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z!@#$%^&*]{8,}/
Его суть я понимаю.
- (?=^[A-Z]) - первый символ пароля имеет верхний регистр
- (?=.*[0-9]) - строка содержит хотя бы одно число;
- (?=.[!@#$%^&]) - строка содержит хотя бы один спецсимвол;
- (?=.*[a-z]) - строка содержит хотя бы одну латинскую букву в нижнем регистре;
- (?=.*[A-Z]) - строка содержит хотя бы одну латинскую букву в верхнем регистре;
- [0-9a-zA-Z!@#$%^&*]{8,} - строка состоит не менее, чем из 8 вышеупомянутых символов.
Но не могу разобраться для чего тут ?= и что оно означает.
Ответы (3 шт):
?= - это так называемое "заглядывание вперёд" (lookahead assertion).
Существует несколько типов такого "заглядывания":
- Заглядывание вперед:
foo(?=bar), совпадётfooтолько передbar, при этом сама строкаbarне войдет в найденный текст. - Отрицательное заглядывание вперед:
foo(?!bar), совпадетfoo, только если после этой строки не следуетbar. - Ретроспективная проверка:
(?<=foo)bar, совпадетbarтолько послеfoo, при этом сама строкаfooне войдет в найденный текст. - Отрицательное заглядывание назад:
foo(?<!bar), совпадетbar, только если перед этой строкой нетfoo.
Конкретно в вашем случае этот прием используется для того, чтобы объединить группы поиска отдельных частей пароля в одну общую сущность, предшествующая часть совпадёт, только в случае если после неё следует то, что указано после ?=
эта регулярка работает так:
- первая буква пароля - заглавная латинская
- она должна стоять перед цифрой (первое
(?=...)) - также она должна стоять перед символом из указанного списка (второе
(?=...)) - также она должна стоять перед малой латинской (третье
(?=...)) - также она должна стоять перед еще одной заглавной латинской (четвертое
(?=...)) - после нее должны стоять минимум восемь знаков из указанного списка
итого, пароль должен начинаться на заглавную латинскую букву и должен состоять не менее чем из 9 знаков, в том числе, цифр, малых и больших латинских и символов.
Знак вопроса ? самостоятельно является квантификатором 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