我的密码强度标准如下:
- 长度为8个字符
- 2个大写字母
- 1个特殊字符
(!@#$&*)
- 2个数字
(0-9)
- 3个小写字母
请问有人能给我编写相应的正则表达式吗?密码必须满足所有条件。
您可以使用正向预查断言来进行这些检查:
^(?=.*[A-Z].*[A-Z])(?=.*[!@#$&*])(?=.*[0-9].*[0-9])(?=.*[a-z].*[a-z].*[a-z]).{8}$
^ 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.
n
的人,将 .{8}
替换为 .{n,}
。 - NullUserException你还应考虑更改一些规则,例如:
通过以上改进,为了更加灵活和易读,我会修改正则表达式为:
^(?=(.*[a-z]){3,})(?=(.*[A-Z]){2,})(?=(.*[0-9]){2,})(?=(.*[!@#$%^&*()\-__+.]){1,}).{8,}$
基本说明
(?=(.*RULE){MIN_OCCURANCES,})
每个规则块都由(?=(){})表示。可以轻松地单独指定和测试规则和出现次数,然后再进行组合。^ 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
最后,为了测试目的,这里有一个与上述正则表达式相对应的robulink
上面给出的答案很完美,但我建议使用多个较小的正则表达式,而不是一个大的。
将长的正则表达式拆分有一些优点:
通常,这种方法使代码更易于维护。
话虽如此,我在这里分享一段我用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 []
}
}
}
你可以使用零长度正向先行断言来单独指定每个约束条件:
(?=.{8,})(?=.*\p{Lu}.*\p{Lu})(?=.*[!@#$&*])(?=.*[0-9])(?=.*\p{Ll}.*\p{Ll})
如果您的正则表达式引擎不支持\p
符号并且仅ASCII足够,那么您可以将\p{Lu}
替换为[A-Z]
,将\p{Ll}
替换为[a-z]
。
以上所有的正则表达式(regex)对我都不起作用。
一个强密码应该遵守以下基本规则:
所以,最佳的正则表达式为:
^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*]).{8,}$
^(?=.*[a-z]{x,})(?=.*[A-Z]{y,})(?=.*[0-9]{z,})(?=.*[!@#\$%\^&\*]).{w,}$
注意: 在正则表达式中更改 x,y,z,w
编辑:更新了正则表达式答案
编辑2:添加了修改
12345678
,你确定它是一个强密码吗?请在发布前尝试你的正则表达式。 - Toto(?!.*pass|.*word|.*1234|.*qwer|.*asdf) exclude common passwords
import re
RegexLength=re.compile(r'^\S{8,}$')
RegexDigit=re.compile(r'\d')
RegexLower=re.compile(r'[a-z]')
RegexUpper=re.compile(r'[A-Z]')
def IsStrongPW(password):
if RegexLength.search(password) == None or RegexDigit.search(password) == None or RegexUpper.search(password) == None or RegexLower.search(password) == None:
return False
else:
return True
while True:
userpw=input("please input your passord to check: \n")
if userpw == "exit":
break
else:
print(IsStrongPW(userpw))
codaddict的解决方案可以正常工作,但这个方案更加高效:(Python语法)
password = re.compile(r"""(?#!py password Rev:20160831_2100)
# Validate password: 2 upper, 1 special, 2 digit, 1 lower, 8 chars.
^ # Anchor to start of string.
(?=(?:[^A-Z]*[A-Z]){2}) # At least two uppercase.
(?=[^!@#$&*]*[!@#$&*]) # At least one "special".
(?=(?:[^0-9]*[0-9]){2}) # At least two digit.
.{8,} # Password length is 8 or more.
$ # Anchor to end of string.
""", re.VERBOSE)
(?#
开始并以 )
结束。 在这个正则表达式中没有不匹配的括号。 - ridgerunnercodaddict给出了一个很好的答案:
^(?=.*[A-Z].*[A-Z])(?=.*[!@#$&*])(?=.*[0-9].*[0-9])(?=.*[a-z].*[a-z].*[a-z]).{8}$
但是如果你想要有8个小写字母而不是3个,可以这样写:
(?=.*[a-z].*[a-z].*[a-z].*[a-z].*[a-z].*[a-z].*[a-z].*[a-z])
这样写起来真的很麻烦,所以你可以这样写
(?=(?:.*[a-z]){8})
?:
用于排除捕获组
因此,我认为更好的答案应该是:
^(?=.*[A-Z].*[A-Z])(?=.*[!@#$&*])(?=.*[0-9].*[0-9])(?=(?:.*[a-z]){3}).{8}$
请注意,(?=.*[a-z]{8})
的工作方式不同,因为它是一个用于匹配8个连续小写字母的正则表达式。
^(?=[A-Z]{2})(?=.*[!@#$&*])(?=.*[0-9]{2})(?=.*[a-z]{3}).{8}$
password
和hello123
是有效的密码!”)。 - Joachim Sauer