Регулярное выражение PHP для проверки сильного пароля [дубликат]

17
задан Peter Mortensen 4 January 2011 в 01:15
поделиться

3 ответа

Лучший способ адаптировать это регулярное выражение - это выбросить его и вместо этого написать код. Требуемое регулярное выражение будет таким длинным и сложным, что вы не сможете прочитать его через два часа после того, как написали. Эквивалентный код PHP будет утомительным, но, по крайней мере, вы сможете понять, что написали.

Между прочим, это не значит, что тебя ударили. Регулярные выражения едва ли подходят для проверки надежности пароля в большинстве случаев, но ваши требования сложнее, чем обычно, и это того не стоит. Кроме того, это регулярное выражение, которое вы опубликовали, - дерьмо. Никогда не доверяйте регулярным выражениям, которые вы найдете в Интернете. Или любой код, если на то пошло. Или, черт возьми, что-нибудь . : - /

31
ответ дан 30 November 2019 в 09:56
поделиться

Я должен согласиться с Аланом. Если существующий regex настолько сложен, зачем пытаться сделать это в одном regex?

Просто разбейте его на простые и доступные шаги. Вы уже сделали это.

Теперь напишите 4 regex для проверки ваших частей, добавьте базовую логику к этим 4 regex и измерьте длину строки. Готово.

Что бы вы предпочли отлаживать, вот это:

(?=^(?:[^A-Z]*[A-Z]){2})(?=^(?:[^a-z]*[a-z]){2})(?=^(?:\D*\d){2})(?=^(?:\w*\W){2})^[A-Za-z\d\W]{8,}$ (который не работает btw. ...)

или вот это:

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;
}

Почему люди считают, что они должны писать регекс, который никто не может понять, только для того, чтобы сделать это одним махом - это выше моих сил...


Ладно, ладно - если вам действительно нужен один regex, узнайте о lookaheads для проверки ваших правил.

Этот монстр делает то, что вы просили, за один раз:

^                                        # 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 

Demo

64
ответ дан 30 November 2019 в 09:56
поделиться

Если вы действительно хотите использовать регулярное выражение, попробуйте следующее:

(?=^(?:[^A-Z]*[A-Z]){2})(?=^(?:[^a-z]*[a-z]){2})(?=^(?:\D*\d){2})(?=^(?:\w*\W){2})^[A-Za-z\d\W]{8,}$

Некоторые пояснения :

  • (? = ^ (?: [^ AZ] * [AZ]) {2}) проверяет наличие двух повторений [^ AZ] * [AZ] , которое является последовательностью ноль или более символов, кроме прописных букв, за которыми следует одна прописная буква
  • (? = ^ (?: [^ az] * [az]) {2}) (то же, что и выше, со строчными буквами)
  • (? = ^ (?: \ D * \ d) {2}) (то же, что и выше, с цифрами)
  • (? = ^ (?: \ W * \ W) {2}) (то же, что и выше, с символами, отличными от слов, но вы можете заменить \ W классом символов любых специальных символов по вашему желанию)
  • ^ [A-Za-z \ d \ W] {8 ,} $ проверяет длину всей строки, состоящей только из символа объединения всех остальных классов символов.
16
ответ дан 30 November 2019 в 09:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: