ereg("/^(?=.*[a-z])(?=.*[0-9])(?=.*[^a-zA-Z0-9])(?=.*[A-Z]).{7,19}$/","ABCabc123!!");
这应该是一个密码验证器,需要大写和小写字母以及数字特殊字符和最小长度 8....但以上返回 false。我究竟做错了什么?
preg_*
,以及更好的验证字符串您正在使用的正则表达式存在(至少)3 个问题:
(?=.*[^a-zA-Z0-9])
何时有更好的选择来执行此操作 - [\W_]
。7
字符且不超过19
, 而不是至少8
.这应该更适合您:
$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;
}
现场演示可以在这里找到。
不要试图在一个正则表达式中完成所有操作。 进行多次正则表达式检查。
我知道您正在编写 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
仅仅因为你可以在一个正则表达式中做到这一点并不意味着你应该。