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

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

4

2 回答 2

8

改为使用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)所指出的那样,多检查可能会更好

正如安迪所提到的,你最好存储一堆规则。这使您可以定制错误消息并轻松添加规则。在 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;
}

现场演示可以在这里找到。

于 2013-09-05T16:34:46.637 回答
4

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

我知道您正在编写 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

当然,这占用了 5 行而不是 1 行,但是在一年中,当您返回并必须添加新规则或弄清楚代码的作用时,您会很高兴以这种方式编写它。也许你以后需要一个数字。简单的!

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

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

于 2013-09-05T17:01:28.090 回答