我正在使用以下正则表达式验证我的密码强度。
^(?=.*[a-z]{1,})(?=.*[A-Z]{1,})(?=.*[0-9]{1,})(?=.*[@\#\$%\^&\+=!\?\*]{1,}).{8,12}$
批准列表中的8-12个字符,至少1个小写字母,1个大写字母,1个数字和1个特殊字符。 (我知道我不能只在前面设置{1,4}并让它正常工作,但我希望尽快解决这个问题,所以我就这样离开了。)
表达式似乎有点冗长,但我的用户可以设置自己的密码规则,这似乎是在正则表达式中创建可互换部分的最佳方式。
为此,我想补充一点,所有字符必须在集合
中[A-Z]|[a-z]|[0-9]|[@\#\$%\^&\+=!\?\*]
如果该组中没有任何字符,则该行不匹配。
不幸的是,我没有找到正确的表达方式。非常感谢任何帮助。
如果与讨论相关,我正在使用.net实现。
答案 0 :(得分:1)
如果找不到集合中定义的任何内容,您可以使用负面外观来使匹配失败。
首先,将所有字符分组到一个类中,并指定您希望通过在开头使用插入符来匹配此类中的任何 not :
[^A-Za-z0-9@\#\$%\^&\+=!\?\*]
接下来,使用此负面字符类和负面外观更新模式:
@"^(?!.*[^A-Za-z0-9@\#\$%\^&\+=!\?\*])(?=.*[a-z]{1,})(?=.*[A-Z]{1,})(?=.*[0-9]{1,})(?=.*[@\#\$%\^&\+=!\?\*]{1,}).{8,12}$"
此外,您通常不需要在字符类中转义元字符,因此您可以通过删除转义来进一步清理模式。这会缩短这种模式:
@"^(?!.*[^A-Za-z0-9@#$%^&+=!?*])(?=.*[a-z]{1,})(?=.*[A-Z]{1,})(?=.*[0-9]{1,})(?=.*[@#$%^&+=!?*]{1,}).{8,12}$"
当然,如果您允许破折号,请务必将其转义或将其放在字符类的开头或结尾,以避免意外指定一系列字符。如果您的用户可以提供模式信息,这很重要,在这种情况下,您可能希望在任何用户提供的输入上使用Regex.Escape method。
答案 1 :(得分:1)
我不明白为什么你这样使用正则表达式。密码不遵循模式,它们遵循一套规则。而不是尝试将其与模式匹配,而是根据一组规则进行检查:
伪代码:
function checkPassword(password, rules)
{
for (i = 0; i < rules.length; i++)
{
if ( !rules[i]( password ) ) return false;
}
return true;
}
function hasCapital(password)
{
return password.matches(/[A-Z]/);
}
function hasLower(password)
{
return password.matches(/[a-z]/);
}
function hasNumber(password)
{
return password.matches(/[0-9]/);
}
function hasSpecial(password)
{
return password.matches(/[@\#\$%\^&\+=!\?\*]/);
}
password = getPassword();
passwordIsValid = false;
rules = [];
rules[] = hasCapital;
rules[] = hasLower;
rules[] = hasNumber;
rules[] = hasSpecial;
passwordIsValid = checkPassword( password, rules );
这种格式是模块化的,您可以指定您想要的任何规则,它会告诉您是否有任何规则被破坏。此外,您会注意到实际使用的RegEx会产生,因此可调试。
如果您使用的是RegEx,它应该简化您的代码,而不是让它更难理解。