我正在尝试在PHP中编写正则表达式,以确保密码符合以下标准:
我写了以下表达式:
$pattern=([a-zA-Z\W+0-9]{8,})
但是,它似乎不符合列出的标准。我能得到另一双眼睛来帮助我吗?
答案 0 :(得分:4)
你的正则表达式 - ([a-zA-Z\W+0-9]{8,})
- 实际上搜索一个长度至少为8个字符的较大文本中的子字符串,但也允许任何英文字母,非字符([a-zA-Z0-9_]
除外),和数字,因此不会强制执行您的2个要求。可以使用look-aheads设置它们。
这是一个固定的正则表达式:
^(?=.*\W.*)(?=.*[A-Z].*).{8,}$
实际上,如果您还要匹配/允许使用非英文字母,则可以将[A-Z]
替换为\p{Lu}
。您还可以考虑使用\p{S}
代替\W
,或者通过添加符号或字符类来进一步确定special character
的标准,例如[\p{P}\p{S}]
(这也将包括所有Unicode标点符号)。
增强的正则表达式版本:
^(?=.*[\p{S}\p{P}].*)(?=.*\p{Lu}.*).{8,}$
人类可读的解释:
^
- 字符串的开头(?=.*\W.*)
- 要求至少有一个非单词字符
(?=.*[\p{S}\p{P}].*)
- 至少1个Unicode特殊符号或标点符号(?=.*[A-Z].*)
- 要求至少有1个大写英文字母
(?=.*\p{Lu}.*)
- 至少1个Unicode字母.{8,}
- 要求至少 8个符号$
- 字符串结尾请参阅Demo 1和Demo 2 (Enhanced regex)
示例代码:
if (preg_match('/^(?=.*\W.*)(?=.*[A-Z].*).{8,}$/u', $header)) {
// PASS
}
else {
# FAIL
}
答案 1 :(得分:2)
使用正面lookahead ?=
,我们确保满足所有密码要求。
至少8个字符长
至少1封大写字母
至少1个特殊字符
^((?=[\S]{8})(?:.*)(?=[A-Z]{1})(?:.*)(?=[\p{S}])(?:.*))$
if (preg_match('/^((?=[\S]{8})(?:.*)(?=[A-Z]{1})(?:.*)(?=[\p{S}])(?:.*))$/u', $password)) {
# Strong Password
} else {
# Weak Password
}
12345678 - WEAK
1234%fff - WEAK
1234_44A - WEAK
133333A$ - STRONG
^ assert position at start of the string
1st Capturing group ((?=[\S]{8})(?:.*)(?=[A-Z]{1})(?:.*)(?=[\p{S}])(?:.*))
(?=[\S]{8}) Positive Lookahead - Assert that the regex below can be matched
[\S]{8} match a single character present in the list below
Quantifier: {8} Exactly 8 times
\S match any kind of visible character [\P{Z}\H\V]
(?:.*) Non-capturing group
.* matches any character (except newline) [unicode]
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
(?=[A-Z]{1}) Positive Lookahead - Assert that the regex below can be matched
[A-Z]{1} match a single character present in the list below
Quantifier: {1} Exactly 1 time (meaningless quantifier)
A-Z a single character in the range between A and Z (case sensitive)
(?:.*) Non-capturing group
.* matches any character (except newline) [unicode]
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
(?=[\p{S}]) Positive Lookahead - Assert that the regex below can be matched
[\p{S}] match a single character present in the list below
\p{S} matches math symbols, currency signs, dingbats, box-drawing characters, etc
(?:.*) Non-capturing group
.* matches any character (except newline) [unicode]
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
$ assert position at end of the string
u modifier: unicode: Pattern strings are treated as UTF-16. Also causes escape sequences to match unicode characters