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

这个PHP正则表达式进行密码验证有什么问题?,php,regex,Php,Regex,这应该是一个密码验证器,需要大写和小写字母以及数字、特殊字符和最小长度为8…但上面的返回值为false。我做错了什么?改用preg.*和更好的验证字符串 您使用的正则表达式(至少)存在3个问题: 当有更好的选择时,您当前正在不必要地检查(?=.[^a-zA-Z0-9]) 您正在检查至少7个字符,且不超过19个,而不是至少8个 你正在使用 您的函数允许在密码中使用空格 这对您来说应该更有效: ereg("/^(?=.*[a-z])(?=.*[0-9])(?=.*[^a-zA-Z0-9])(?=.*

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

改用
preg.*
和更好的验证字符串 您使用的正则表达式(至少)存在3个问题:

  • 当有更好的选择时,您当前正在不必要地检查
    (?=.[^a-zA-Z0-9])
  • 您正在检查至少
    7个
    字符,且不超过
    19个
    ,而不是至少
    8个
  • 你正在使用
  • 您的函数允许在密码中使用空格
  • 这对您来说应该更有效:

    ereg("/^(?=.*[a-z])(?=.*[0-9])(?=.*[^a-zA-Z0-9])(?=.*[A-Z]).{7,19}$/","ABCabc123!!");
    
    此正则表达式的组件说明:

    $regex = "/^\S*(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[\d])(?=\S*[\W_])(?=\S{8,})\S*$/";
    $valid = (bool) preg_match($regex,$password);
    
    正如安迪·莱斯特所指出的那样,多检查可能会让你受益匪浅

    正如Andy提到的,你最好保存一堆规则。这允许您定制错误消息并轻松添加规则。在PHP中,我将以以下方式实现:

    /            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
    
    可以找到现场演示。

    使用
    preg.*
    和更好的验证字符串 您使用的正则表达式(至少)存在3个问题:

  • 当有更好的选择时,您当前正在不必要地检查
    (?=.[^a-zA-Z0-9])
  • 您正在检查至少
    7个
    字符,且不超过
    19个
    ,而不是至少
    8个
  • 你正在使用
  • 您的函数允许在密码中使用空格
  • 这对您来说应该更有效:

    ereg("/^(?=.*[a-z])(?=.*[0-9])(?=.*[^a-zA-Z0-9])(?=.*[A-Z]).{7,19}$/","ABCabc123!!");
    
    此正则表达式的组件说明:

    $regex = "/^\S*(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[\d])(?=\S*[\W_])(?=\S{8,})\S*$/";
    $valid = (bool) preg_match($regex,$password);
    
    正如安迪·莱斯特所指出的那样,多检查可能会让你受益匪浅

    正如Andy提到的,你最好保存一堆规则。这允许您定制错误消息并轻松添加规则。在PHP中,我将以以下方式实现:

    /            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
    

    可以找到实时演示。

    不要试图在一个正则表达式中完成所有操作。进行多个正则表达式检查

    我知道您正在编写PHP,但我更了解Perl,所以请跟随我的思路

    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;
    }
    
    当然,这会占用五行而不是一行,但是一年后,当你回到过去,不得不添加一条新规则,或者弄清楚代码的作用时,你会很高兴你是这样写的。也许你以后需要一个数字。轻松点

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

    仅仅因为你可以在一个正则表达式中完成,并不意味着你应该这样做。

    不要试图在一个正则表达式中完成所有操作。进行多个正则表达式检查

    我知道您正在编写PHP,但我更了解Perl,所以请跟随我的思路

    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;
    }
    
    当然,这会占用五行而不是一行,但是一年后,当你回到过去,不得不添加一条新规则,或者弄清楚代码的作用时,你会很高兴你是这样写的。也许你以后需要一个数字。轻松点

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

    仅仅因为你可以在一个正则表达式中完成它并不意味着你应该这样做。

    有大量的正则表达式测试页面。很多人会突出显示测试字符串中的匹配部分。有很多regex tester页面。许多人会突出显示测试字符串中的匹配部分。如果pswd包含下划线,则会失败,因为这不是OP想要的<代码>(?=.[^a-zA-Z0-9])必须匹配特殊字符。@M42已修复。我甚至写了评论,但没有在特殊字符的捕获组中添加下划线。在第一句话中,你的意思是说他应该使用
    preg_match()
    ?您自己肯定没有使用
    preg\u replace()
    。如果pswd包含下划线,它将失败,这不是OP想要的<代码>(?=.[^a-zA-Z0-9])必须匹配特殊字符。@M42已修复。我甚至写了评论,但没有在特殊字符的捕获组中添加下划线。在第一句话中,你的意思是说他应该使用
    preg_match()
    ?您肯定没有自己使用
    preg\u replace()
    。这也可以在
    foreach
    循环中使用
    数组
    的验证器来完成,我通常会这样做+1.在我的回答中添加了一种PHP风格的方法,这要归功于您。这也可以通过
    foreach
    循环和
    数组
    的验证器来完成,这也是我通常的做法+1.在我的回答中添加了一种PHP风格的方法,谢谢。