PHP регулярное выражение для надежной проверки пароля
Я видел следующее регулярное выражение в Интернете.
(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$
Проверяется только если строка:
* contain at least (1) upper case letter
* contain at least (1) lower case letter
* contain at least (1) number or special character
* contain at least (8) characters in length
Я хотел бы знать, как преобразовать это регулярное выражение, чтобы он проверял строку в
* contain at least (2) upper case letter
* contain at least (2) lower case letter
* contain at least (2) digits
* contain at least (2) special character
* contain at least (8) characters in length
Ну, если он содержит как минимум 2 верхние, нижние, цифры и специальные символы, тогда мне не понадобится длина 8 символов.
Специальные символы включают в себя:
! `~ @#$%^&*()_-+=[]\|{};:'",/<>.?
3 ответа
Лучший способ адаптировать это регулярное выражение - выкинуть его и вместо этого написать некоторый код. Требуемое регулярное выражение будет настолько длинным и сложным, что вы не сможете прочитать его через два часа после его написания. Эквивалентный PHP-код будет утомительным, но по крайней мере вы сможете понять, что вы написали.
Кстати, это не для тебя Регулярные выражения в большинстве случаев просто плохо подходят для проверки надежности пароля, но ваши требования сложнее, чем обычно, и это просто не стоит. Кроме того, это регулярное выражение, которое вы разместили, является дерьмом. Никогда не доверяйте регулярным выражениям, которые вы находите в Интернете. Или любой код, в этом отношении. Или, черт возьми, что угодно.:-/
Я должен согласиться с Аланом. Если существующее регулярное выражение настолько сложно, зачем пытаться сделать это всего за одно регулярное выражение?
Просто разбейте его на простые доступные шаги. Вы уже сделали это.
Теперь напишите 4 регулярных выражения для проверки ваших частей, добавьте базовую логику к 4 регулярным выражениям и измерьте длину строки. Готово.
Что бы вы предпочли отладить, это:
(?=^(?:[^A-Z]*[A-Z]){2})(?=^(?:[^a-z]*[a-z]){2})(?=^(?:\D*\d){2})(?=^(?:\w*\W){2})^[A-Za-z\d\W]{8,}$
(что не работает, кстати...)
или это:
function valid_pass($candidate) {
$r1='/[A-Z]/'; //Uppercase
$r2='/[a-z]/'; //lowercase
$r3='/[!@#$%^&*()\-_=+{};:,<.>]/'; // whatever you mean by 'special char'
$r4='/[0-9]/'; //numbers
if(preg_match_all($r1,$candidate, $o)<2) return FALSE;
if(preg_match_all($r2,$candidate, $o)<2) return FALSE;
if(preg_match_all($r3,$candidate, $o)<2) return FALSE;
if(preg_match_all($r4,$candidate, $o)<2) return FALSE;
if(strlen($candidate)<8) return FALSE;
return TRUE;
}
Почему люди чувствуют, что им нужно написать регулярное выражение, которое никто не может понять, просто так, что они могут сделать это за один раз, мне не под силу...
Хорошо, хорошо - если вы действительно хотите использовать одно регулярное выражение, узнайте о перспективах, чтобы подтвердить свои правила.
Этот монстр делает то, что вы просили за один раз:
^ # start of line
(?=(?:.*[A-Z]){2,}) # 2 upper case letters
(?=(?:.*[a-z]){2,}) # 2 lower case letters
(?=(?:.*\d){2,}) # 2 digits
(?=(?:.*[!@#$%^&*()\-_=+{};:,<.>]){2,}) # 2 special characters
(.{8,}) # length 8 or more
$ # EOL
Если вы действительно хотите использовать регулярное выражение, попробуйте это:
(?=^(?:[^A-Z]*[A-Z]){2})(?=^(?:[^a-z]*[a-z]){2})(?=^(?:\D*\d){2})(?=^(?:\w*\W){2})^[A-Za-z\d\W]{8,}$
Некоторое объяснение:
(?=^(?:[^A-Z]*[A-Z]){2})
тесты для двух повторений[^A-Z]*[A-Z]
которая представляет собой последовательность из нуля или более символов, кроме заглавных букв, за которыми следует одна заглавная буква(?=^(?:[^a-z]*[a-z]){2})
(так же, как и выше, строчными буквами)(?=^(?:\D*\d){2})
(так же, как выше с цифрами)(?=^(?:\w*\W){2})
(так же, как и выше, с несловесными символами, но вы можете изменить\W
с классом символов любых специальных символов, которые вы хотите)^[A-Za-z\d\W]{8,}$
проверяет длину всей строки, состоящей только из символа объединения всех других классов символов.