【发布时间】:2017-02-26 10:17:50
【问题描述】:
我目前正在使用正则表达式进行一些测试。我有一个要求检查强密码的练习,这意味着它应该有:至少一个数字,一个小写字母,一个大写字母,没有空格,至少一个 不是字母或数字的字符。它应该在 8-16 个字符之间。
我写了这段代码:
<?php
$passwords = array("Jtuhn", "12J@k", "jok", "Joan 12@45", "Jghf2@45", "Joan=?j123j");
foreach($passwords as $pass)
{
///^\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*$/
if(strlen($pass) >= 8 && strlen($pass) < 17)
{
if(preg_match("/^\w*(?=\w*\d)(?=\w*[A-Z])(?=\w*[^0-9A-Za-z])(?=\w*[a-z])\w*$/", $pass) )
echo "$pass => MATCH<br>";
else
echo "$pass => FAIL<br>";
}
else
echo "$pass => FAIL(because of length)<br>";
}
?>
最后两个应该匹配,但它们失败了。我认为问题在于
(?=\w*[^0-9A-Za-z])
这应该是模式匹配,至少有一个字符不是字母或数字,但我不知道为什么。 我知道这个强密码已在互联网上解决,但这不是我的问题。我的问题是为什么这部分工作没有做应该做的事情。
【问题讨论】:
-
强密码是不可预测的密码,而正则表达式检查模式。如果某事遵循某种模式,则无法预测……此外,17 个字符的密码比 16 个字符的密码强,所以这是一个愚蠢的限制。
-
@Narf 好吧,我认为这没什么大不了的。我真正的问题是模式。假设 (?=\w*[^0-9A-Za-z]) 检查顺序无关紧要的特殊字符。但这不起作用。如果我删除它,如果密码包含一个大写字母、一个小写字母和一个数字,则模式可以很好地验证密码。当我添加那个时,它什么都不验证,都失败了。
-
你的正则表达式是
^\w*[lookaheads]\w*$。它不会匹配任何包含特殊字符的内容,并且它很容易发生灾难性的回溯。 -
@Rawing 为什么会这样?我应该从正则表达式中删除任何内容吗?
-
只需在字符串开头触发前瞻断言。您的主要条件是匹配 8-16 个 非空格字符
^\S{8,16}$并将您的条件添加到^start like this。