duancan9815 2013-09-05 16:01
浏览 23
已采纳

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

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

This is supposed to be a password validator, requiring alphabets in upper and lowercases along with numbers special chars and mininmum length of 8....but the above returns false. What am I doing wrong?

  • 写回答

2条回答 默认 最新

  • dsfhd78978 2013-09-05 16:34
    关注

    Use preg_* instead, and a better validation string

    There are (at least) 3 issues with the regex you're using:

    1. You're currently needlessly checking for (?=.*[^a-zA-Z0-9]) when there is a better option to do this - [\W_].
    2. You're checking for at least 7 characters and no more than 19, rather than at least 8.
    3. You're using a deprecated function.
    4. Your function allows whitespace in passwords.

    This should work better for you:

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

    Explanation of the components of this regex:

    /            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
    

    As pointed out by Andy Lester, you may be better off with multiple checks

    As Andy mentioned, you're best off storing a bunch of rules. This allows you to tailor your error messages and add rules easily. In PHP I'd implement this in this way:

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

    Live demonstration can be found here.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 微信会员卡接入微信支付商户号收款
  • ¥15 如何获取烟草零售终端数据
  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?