密码正则表达式有四个标准

时间:2015-04-24 20:24:16

标签: php regex

我正在尝试在PHP中编写正则表达式,以确保密码符合以下标准:

  • 它至少应该有8个字符
  • 至少应包含一个特殊字符
  • 至少应包含一个大写字母。

我写了以下表达式:

$pattern=([a-zA-Z\W+0-9]{8,})

但是,它似乎不符合列出的标准。我能得到另一双眼睛来帮助我吗?

2 个答案:

答案 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.*) - 要求至少有一个非单词字符
    OR (?=.*[\p{S}\p{P}].*) - 至少1个Unicode特殊符号或标点符号
  • (?=.*[A-Z].*) - 要求至少有1个大写英文字母
    OR (?=.*\p{Lu}.*) - 至少1个Unicode字母
  • .{8,} - 要求至少 8个符号
  • $ - 字符串结尾

请参阅Demo 1Demo 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}])(?:.*))$

PHP实现:

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

演示:

https://regex101.com/r/hE2dD2/1