正则表达式验证密码强度

Aja*_*kar 131 regex passwords

我的密码强度标准如下:

  • 8个字符长度
  • 大写字母2个字母
  • 1特殊字符 (!@#$&*)
  • 2个数字 (0-9)
  • 小写3个字母

有人可以给我正则表达式.密码必须满足所有条件.

cod*_*ict 398

您可以使用正向预测断言进行这些检查:

^(?=.*[A-Z].*[A-Z])(?=.*[!@#$&*])(?=.*[0-9].*[0-9])(?=.*[a-z].*[a-z].*[a-z]).{8}$
Run Code Online (Sandbox Code Playgroud)

Rubular链接

说明:

^                         Start anchor
(?=.*[A-Z].*[A-Z])        Ensure string has two uppercase letters.
(?=.*[!@#$&*])            Ensure string has one special case letter.
(?=.*[0-9].*[0-9])        Ensure string has two digits.
(?=.*[a-z].*[a-z].*[a-z]) Ensure string has three lowercase letters.
.{8}                      Ensure string is of length 8.
$                         End anchor.
Run Code Online (Sandbox Code Playgroud)

  • 对于任何想要长度至少为'n`的人,用`.{n,}`替换`.{8}` (85认同)
  • +1以获得完整的解释.我的密码规则不同,但根据你的回答,我可以调整正则表达式. (13认同)
  • 感谢您描述正则表达式中发生的事情.对于我们这些从未真正掌握语法的人来说,这是一个很好的学习范例. (13认同)
  • 我也很欣赏正则表达式的解释.我多次使用我发现的复杂正则表达式,却没有真正理解发生了什么. (3认同)
  • 积极向前看正是用于这类事情的东西.这是我的:^(?=.*[AZ])(?=.*[az])(?=.*[0-9]).{8,24} $(8到24个字符之间,至少有一个每种类型的小写,大写和数字) (2认同)
  • 对于1个大写字母,1个小写字母,1个数字,1个特殊字符和n个字符的最小长度:-^(?=。* [AZ])(?=。* [!@#$&*])(?= 。* [0-9])(?=。* [az])。{n,} $非常感谢您的解释 (2认同)
  • 伟大的模式,我想知道为什么不使用量词?至少1个特殊,1个数字,1个特殊字符,8个字符:^(?=.*([AZ]){1,})(?=.*[!@#$&*] {1,})( ?=.*[0-9] {1,})(?=.*[AZ] {1,}).{8100} $ (2认同)

Joa*_*uer 11

您可以使用零长度正向预测来分别指定每个约束:

(?=.{8,})(?=.*\p{Lu}.*\p{Lu})(?=.*[!@#$&*])(?=.*[0-9])(?=.*\p{Ll}.*\p{Ll})
Run Code Online (Sandbox Code Playgroud)

如果您正则表达式引擎不支持的\p符号和纯ASCII就够了,那么你就可以替换\p{Lu}使用[A-Z],并\p{Ll}[a-z].


Jun*_*tri 11

不幸的是,上述所有正则表达式都不适合我。强密码的基本规则是

  • 应至少包含一个大写字母
  • 应至少包含一个小写字母
  • 应至少包含一个数字
  • 应至少包含一个特殊字符
  • 和最小长度

所以,最好的正则表达式是

^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*]).{8,}$
Run Code Online (Sandbox Code Playgroud)

上述正则表达式的最小长度为 8。您可以将其从 {8,} 更改为 { any_number ,}

规则修改?

假设您想要最少x 个字符小写字母,y 个字符大写字母,z个字符数字,总最小长度w。然后尝试下面的正则表达式

^(?=.*[a-z]{x,})(?=.*[A-Z]{y,})(?=.*[0-9]{z,})(?=.*[!@#\$%\^&\*]).{w,}$
Run Code Online (Sandbox Code Playgroud)

注意:更改正则表达式中的x , y , z , w

编辑:更新了正则表达式答案

编辑2:添加修改


lsu*_*guy 9

您还应该考虑将一些规则更改为:

  1. 添加更多特殊字符,即 %、^、(、)、-、_、+ 和句点。我正在添加您在美式键盘中的数字符号上方遗漏的所有特殊字符。转义正则表达式使用的那些。
  2. 将密码设为 8 个或更多字符。不只是一个静态数字 8。

通过上述改进,并且为了获得更大的灵活性和可读性,我将正则表达式修改为。

^(?=(.*[a-z]){3,})(?=(.*[A-Z]){2,})(?=(.*[0-9]){2,})(?=(.*[!@#$%^&*()\-__+.]){1,}).{8,}$
Run Code Online (Sandbox Code Playgroud)

基本说明

(?=(.*RULE){MIN_OCCURANCES,})     
Run Code Online (Sandbox Code Playgroud)

每个规则块由 (?=(){}) 显示。然后可以轻松地指定规则和出现次数,并在组合之前单独测试

详细说明

^                               start anchor
(?=(.*[a-z]){3,})               lowercase letters. {3,} indicates that you want 3 of this group
(?=(.*[A-Z]){2,})               uppercase letters. {2,} indicates that you want 2 of this group
(?=(.*[0-9]){2,})               numbers. {2,} indicates that you want 2 of this group
(?=(.*[!@#$%^&*()\-__+.]){1,})  all the special characters in the [] fields. The ones used by regex are escaped by using the \ or the character itself. {1,} is redundant, but good practice, in case you change that to more than 1 in the future. Also keeps all the groups consistent
{8,}                            indicates that you want 8 or more
$                               end anchor
Run Code Online (Sandbox Code Playgroud)

最后,出于测试目的,这里是一个带有上述正则表达式的robulink


Luc*_*nzo 6

上面给出的答案是完美的,但我建议使用多个较小的正则表达式而不是大的正则表达式.
拆分长正则表达式有一些优点:

  • 易于书写和阅读
  • 容易调试
  • 容易添加/删除部分正则表达式

通常,这种方法可以使代码易于维护.

话虽如此,我分享了一段我在Swift中编写的代码示例:

struct RegExp {

    /**
     Check password complexity

     - parameter password:         password to test
     - parameter length:           password min length
     - parameter patternsToEscape: patterns that password must not contains
     - parameter caseSensitivty:   specify if password must conforms case sensitivity or not
     - parameter numericDigits:    specify if password must conforms contains numeric digits or not

     - returns: boolean that describes if password is valid or not
     */
    static func checkPasswordComplexity(password password: String, length: Int, patternsToEscape: [String], caseSensitivty: Bool, numericDigits: Bool) -> Bool {
        if (password.length < length) {
            return false
        }
        if caseSensitivty {
            let hasUpperCase = RegExp.matchesForRegexInText("[A-Z]", text: password).count > 0
            if !hasUpperCase {
                return false
            }
            let hasLowerCase = RegExp.matchesForRegexInText("[a-z]", text: password).count > 0
            if !hasLowerCase {
                return false
            }
        }
        if numericDigits {
            let hasNumbers = RegExp.matchesForRegexInText("\\d", text: password).count > 0
            if !hasNumbers {
                return false
            }
        }
        if patternsToEscape.count > 0 {
            let passwordLowerCase = password.lowercaseString
            for pattern in patternsToEscape {
                let hasMatchesWithPattern = RegExp.matchesForRegexInText(pattern, text: passwordLowerCase).count > 0
                if hasMatchesWithPattern {
                    return false
                }
            }
        }
        return true
    }

    static func matchesForRegexInText(regex: String, text: String) -> [String] {
        do {
            let regex = try NSRegularExpression(pattern: regex, options: [])
            let nsString = text as NSString
            let results = regex.matchesInString(text,
                options: [], range: NSMakeRange(0, nsString.length))
            return results.map { nsString.substringWithRange($0.range)}
        } catch let error as NSError {
            print("invalid regex: \(error.localizedDescription)")
            return []
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我建议添加

(?!.*pass|.*word|.*1234|.*qwer|.*asdf) exclude common passwords
Run Code Online (Sandbox Code Playgroud)