【问题标题】:Password Regular expression with four criteria具有四个条件的密码正则表达式
【发布时间】:2015-04-29 02:17:04
【问题描述】:

我正在尝试在 PHP 中编写一个正则表达式,以确保密码符合以下条件:

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

我写了如下表达式:

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

但是,它似乎无法按照列出的标准工作。请问我可以再找一双眼睛来帮助我吗?

【问题讨论】:

    标签: php regex


    【解决方案1】:

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

    Demo 1Demo 2 (Enhanced regex)

    示例代码:

    if (preg_match('/^(?=.*\W.*)(?=.*[A-Z].*).{8,}$/u', $header)) {
     // PASS
    } 
    else {
        # FAIL
    }
    

    【讨论】:

    • 我认为 OP 说“至少 8 个字符长”,而不是 8 个字符长。
    • 通常,密码不包含空格,但 OP 并没有具体说明,对此也没有规定。
    【解决方案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

    【讨论】:

      猜你喜欢
      • 2011-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      相关资源
      最近更新 更多