用于强密码验证的PHP正则表达式

时间:2010-04-14 13:51:49

标签: php regex validation passwords

我在网上看到了以下正则表达式。

(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$

仅在字符串:

时验证
   * contain at least (1) upper case letter
   * contain at least (1) lower case letter
   * contain at least (1) number or special character
   * contain at least (8) characters in length

我想知道如何转换这个正则表达式,以便它检查字符串

* contain at least (2) upper case letter
* contain at least (2) lower case letter
* contain at least (2) digits
* contain at least (2) special character
* contain at least (8) characters in length

好吧,如果它包含至少2个上,下,数字和特殊字符,那么我不会 需要8个字符长度。

特殊字符包括:

  !

`〜@#$%^&安培; *()_- + = [] \ | {} ;:”',/<?>

3 个答案:

答案 0 :(得分:63)

我必须同意艾伦。如果现有的正则表达式如此复杂,为什么只在一个正则表达式中尝试呢?

将其分解为平易近人的简单步骤。你已经做到了。

现在编写4个正则表达式来验证您的部件,将基本逻辑添加到4个正则表达式并测量字符串的长度。完成。

您更愿意调试,这个:

(?=^(?:[^A-Z]*[A-Z]){2})(?=^(?:[^a-z]*[a-z]){2})(?=^(?:\D*\d){2})(?=^(?:\w*\W){2})^[A-Za-z\d\W]{8,}$(这不起作用......)

或者这个:

function valid_pass($candidate) {
   $r1='/[A-Z]/';  //Uppercase
   $r2='/[a-z]/';  //lowercase
   $r3='/[!@#$%^&*()\-_=+{};:,<.>]/';  // whatever you mean by 'special char'
   $r4='/[0-9]/';  //numbers

   if(preg_match_all($r1,$candidate, $o)<2) return FALSE;

   if(preg_match_all($r2,$candidate, $o)<2) return FALSE;

   if(preg_match_all($r3,$candidate, $o)<2) return FALSE;

   if(preg_match_all($r4,$candidate, $o)<2) return FALSE;

   if(strlen($candidate)<8) return FALSE;

   return TRUE;
}

为什么大家觉得他们必须写一个没有人能够理解的正则表达式,所以他们可以一次性完成它是超出我的...


好的 - 如果你真的想要一个正则表达式,请了解lookaheads以验证你的规则。

这个怪物一次性完成了你的要求:

^                                        # start of line
(?=(?:.*[A-Z]){2,})                      # 2 upper case letters
(?=(?:.*[a-z]){2,})                      # 2 lower case letters
(?=(?:.*\d){2,})                         # 2 digits
(?=(?:.*[!@#$%^&*()\-_=+{};:,<.>]){2,})  # 2 special characters
(.{8,})                                  # length 8 or more
$                                        # EOL 

Demo

答案 1 :(得分:31)

适应该正则表达式的最佳方法是将其删除并编写一些代码。所需的正则表达式将是如此漫长而复杂,您在编写它之后两小时就无法读取它。等效的PHP代码将是乏味的,但至少你将能够理解你所写的内容。

顺便说一句,这并不意味着对你的抨击。在大多数情况下,正则表达式几乎不适合密码强度验证,但是您的要求比平常更复杂,而且它不值得。另外,你发布的正则表达式是垃圾。永远不要相信你发现在网络上漂浮的正则表达式。或者任何代码,就此而言。或者,哎呀,任何。 : - /

答案 2 :(得分:16)

如果你真的想使用正则表达式,试试这个:

(?=^(?:[^A-Z]*[A-Z]){2})(?=^(?:[^a-z]*[a-z]){2})(?=^(?:\D*\d){2})(?=^(?:\w*\W){2})^[A-Za-z\d\W]{8,}$

一些解释:

  • (?=^(?:[^A-Z]*[A-Z]){2})测试两次重复的[^A-Z]*[A-Z],这是一个零个或多个字符的序列,除了大写字母后跟一个大写字母
  • (?=^(?:[^a-z]*[a-z]){2})(与上面的小写字母相同)
  • (?=^(?:\D*\d){2})(与上面的数字相同)
  • (?=^(?:\w*\W){2})(与上面的非单词字符相同,但您可以使用您想要的任何特殊字符的字符类更改\W
  • ^[A-Za-z\d\W]{8,}$测试整个字符串的长度,该字符串仅由所有其他字符类的并集字符组成。