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,}$ проверяет длину всей строки, состоящей только из символа объединения всех других классов символов.
Другие вопросы по тегам