正则表达式不能很好地检查密码


Regular Expression does not check against passwords well

我需要检查密码是否只包含英文数字和字母。我使用以下正则表达式:

if (!preg_match("^[A-Za-z0-9 _]*$^", $_POST['password']))
{
// show error
}
{

但这不起作用,并且允许其他语言的字符而不停止提交。问题出在哪里?

删除preg_match末尾的^^的意思是(如果作为第一个字符找到)开始,如果它是结束,它的意思是字符^应该出现,但由于$出现在它之前,它的含义令人困惑,可能意味着几件事,最"可能"的是在结束后的字符^

使用regexpal.com测试正则表达式。

事实上,我会把它改成这个:

if (preg_match("[^A-Za-z0-9 _]", $_POST['password']))
{
  // invalid character
}

没有"英文"数字或字母这样的东西。许多语言是(或可以)使用与英语相同的字母表书写的。它通常被称为拉丁字母表。

如果您真的只想接受拉丁字母数字字符,请使用:

if preg_match("/^[a-zA-Z0-9]+$/", $_POST['password']) {
  //good to go
} else {
  //I don't like this password
}

原始正则表达式有一个额外的尾部^,它允许使用空格和下划线。你希望这些字符也被允许吗?如果是,请使用^['w ]+$

然而,如果你这样做是为了限制密码可以包含的字符,你有没有停下来思考一下你在做什么?限制您接受的密码字符集会大大降低它们的强度。您应该允许尽可能广泛的字符范围,以允许用户选择强密码。

如果您正在检查以检测弱密码,请忽略。然而,你还应该考虑其他因素,比如长度和字典单词的存在。请参阅此答案以了解一些优秀的细节。

与此相关的是,你是否以哈希形式存储用户的密码?这是绝对必要的。

尝试

preg_match('/^['w]+$/', $_POST['password'] ) instead ! 

备选方案:

preg_match("/^[a-zA-Z0-9]+$/", $_POST['password'])

preg_match()等使用在第一个字符中设置的分隔符。这将结束正则表达式,之后字符串必须结束,或者只能指定修饰符。

因此,您的代码应该是例如

if (!preg_match('`^[A-Za-z0-9 _]+$`', $_POST['password']))
{
// show error
}
{

您使用^作为分隔符,但应该使用它来使正则表达式从字符串开始匹配,因此我使用backtick`,因为它很少在字符串中使用(其他人会使用/)。

此外,使用单引号是因为双引号"允许引用美元变量,但您希望$表示要匹配的密码的末尾。

还有一件事:匹配[...]*也会允许空密码,这是你不应该鼓励的,因此是+(尽管如果你希望密码至少包含n个字符,即使用[...]{n,}进行匹配,这是有争议的)。