这个PHP正则表达式进行密码验证有什么问题


What is wrong with this PHP regex to do password validation?

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

这应该是一个密码验证器,需要大写和小写字母以及数字特殊字符和最小长度为 8....但上述返回 false。我做错了什么?

改用preg_*,以及更好的验证字符串

您使用的正则表达式(至少(存在 3 个问题:

  1. 您目前正在不必要地检查(?=.*[^a-zA-Z0-9])何时有更好的选择 - ['W_] .
  2. 您正在检查至少 7 个字符且不超过 19 个字符,而不是至少8 个字符。
  3. 您正在使用已弃用的函数。
  4. 您的函数允许在密码中使用空格。

这应该更适合您:

$regex = "/^'S*(?='S*[a-z])(?='S*[A-Z])(?='S*['d])(?='S*['W_])(?='S{8,})'S*$/";
$valid = (bool) preg_match($regex,$password);

此正则表达式组件的说明:

/            Delimiter
^            Start of string anchor
'S*          Any string without whitespace
(?='S*[a-z]) Must contain at least 1 lowercase letter
(?='S*[A-Z]) 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

正如安迪·莱斯特(Andy Lester(所指出的,多次检查可能会更好

正如Andy提到的,你最好存储一堆规则。这使您可以定制错误消息并轻松添加规则。在PHP中,我会以这种方式实现这一点:

function validatePassword($password) {
    $rules = array(
        'no_whitespace' => '/^'S*$/',
        'match_upper'   => '/[A-Z]/',
        'match_lower'   => '/[a-z]/',
        '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 =~ /[a-z]/) &&  # Has lowercase
    ($pw =~ /[A-Z]/) &&  # Has uppercase
    ($pw =~ /'W/);       # Has special character

当然,这占用了五行而不是一行,但是在一年内,当你回去必须添加新规则,或者弄清楚代码的作用时,你会很高兴你以这种方式编写它。 也许你以后需要一个数字。 容易!

my $password_is_valid =
    length($pw) >= 8 &&  # Length >= 8
    ($pw =~ /'d/)    &&  # Has digit
    ($pw =~ /[a-z]/) &&  # Has lowercase
    ($pw =~ /[A-Z]/) &&  # Has uppercase
    ($pw =~ /'W/);       # Has special character

仅仅因为您可以在一个正则表达式中做到这一点并不意味着您应该这样做