Что не так с этим регулярным выражением PHP для проверки пароля?

ereg("/^(?=.*[az])(?=.*[0-9])(?=.*[^a-zA-Z0-9])(?=.*[AZ]).{7,19}$/","ABCabc123!!"); 

Предполагается, что это валидатор паролей, требующий алфавитов в верхних и нижних строках вместе с номерами специальных символов и длиной mininmum 8 …. но приведенное выше возвращает false. Что я делаю не так?

Solutions Collecting From Web of "Что не так с этим регулярным выражением PHP для проверки пароля?"

preg_* этого используйте preg_* и лучшую строку проверки

Есть (по крайней мере) 3 вопроса с регулярным выражением, которое вы используете:

  1. В настоящее время вы не нуждаетесь в проверке (?=.*[^a-zA-Z0-9]) когда есть лучший вариант для этого – [\W_] .
  2. Вы проверяете как минимум 7 символов и не более 19 , а не как минимум 8 .
  3. Вы используете устаревшую функцию .
  4. Ваша функция позволяет пропуски в паролях.

Это должно работать лучше для вас:

 $regex = "/^\S*(?=\S*[az])(?=\S*[AZ])(?=\S*[\d])(?=\S*[\W_])(?=\S{8,})\S*$/"; $valid = (bool) preg_match($regex,$password); 

Объяснение компонентов этого регулярного выражения:

 / Delimiter ^ Start of string anchor \S* Any string without whitespace (?=\S*[az]) Must contain at least 1 lowercase letter (?=\S*[AZ]) Must contain at least 1 uppercase letter (?=\S*[\d]) Must contain at least 1 digit (?=\S*[\W_]) Must contain at least 1 special character (note: \W will not consider underscore '_' a special character) (?=\S{8,}) Must contain at least 8 characters $ End of string anchor 

Как отметил Энди Лестер, вам может быть лучше с несколькими проверками

Как заметил Энди, лучше всего сохранить кучу правил. Это позволяет вам адаптировать сообщения об ошибках и легко добавлять правила. В PHP я бы реализовал это следующим образом:

 function validatePassword($password) { $rules = array( 'no_whitespace' => '/^\S*$/', 'match_upper' => '/[AZ]/', 'match_lower' => '/[az]/', 'match_number' => '/\d/', 'match_special' => '/[\W_]/', 'length_abv_8' => '/\S{8,}/' ); $valid = true; foreach($rules as $rule) { $valid = $valid && (bool) preg_match($rule, $password); if($valid !== true) break; } return (bool) $valid; } 

Живую демонстрацию можно найти здесь .

Не пытайтесь делать все это в одном регулярном выражении. Сделайте несколько проверок регулярных выражений.

Я знаю, что вы пишете PHP, но я знаю, что Perl лучше, поэтому следуйте за идеей.

 my $password_is_valid = length($pw) >= 8 && # Length >= 8 ($pw =~ /[az]/) && # Has lowercase ($pw =~ /[AZ]/) && # Has uppercase ($pw =~ /\W/); # Has special character 

Конечно, это занимает пять строк вместо одного, но через год, когда вы вернетесь и должны добавить новое правило, или выяснить, что делает код, вы будете рады, что вы его так написали. Возможно, вам понадобится цифра позже. Легко!

 my $password_is_valid = length($pw) >= 8 && # Length >= 8 ($pw =~ /\d/) && # Has digit ($pw =~ /[az]/) && # Has lowercase ($pw =~ /[AZ]/) && # Has uppercase ($pw =~ /\W/); # Has special character 

Просто потому, что вы можете сделать это в одном регулярном выражении, это не значит, что вам нужно .