【问题标题】:secured password with regular expression带有正则表达式的安全密码
【发布时间】:2012-10-04 06:27:59
【问题描述】:

我对正则表达式很陌生,我做了一个研究,有点了解 我需要的是一个符合这些规范的密码

  1. 任何字母字符(至少一个)
  2. 任何数字字符(至少一个)
  3. 没有空格
  4. 特殊字符(0 个或多个)

我要做的是这个

^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]+)(?!\S)$

匹配 1、2、3 规范但不匹配 4 我在 4 上尝试了不同的东西,但我失败了

谁能帮帮我?

【问题讨论】:

    标签: php regex passwords character


    【解决方案1】:

    你很亲密。这似乎解决了你的问题:

    preg_match("/^(?=.*[0-9])(?=.*[a-z])(\S+)$/i", $password)
    

    我做了两个改动。

    1. 通过使用i 修饰符(不区分大小写匹配)稍微缩短。这允许删除 A-Z`。
    2. 我认为(?!\S) 在这里并没有真正的帮助。相反,您可以简单地使您的实际匹配只包含非空格字符(\S+)。这也将立即允许您的密码中包含特殊字符(除了空格之外的任何字符)。

    如果您只想允许特定的特殊字符集,请将\S 替换为包含字母、数字和您希望允许的所有字符的字符类。顺便说一句,如果您想确保您的密码有一定的最小长度,您可以将 + 更改为 {8,} 例如。

    【讨论】:

    • 完美的工作,谢谢,我想 +100 :) 你,但它需要 15 声望,我只有 8,再次感谢你 :)
    • 或者更快.../^(?=[^0-9]*[0-9])(?=[^a-z]*[a-z])(\S+)$/i
    【解决方案2】:

    不需要奇怪的正则表达式。尤其是因为您要确保密码包含不包含,并且无论它出现在哪里都没关系:

    <?php
    
    /**
     * Validates the password:
     *  * Has at least one alphabet character
     *  * Has at least one digit
     *  * Has no spaces
     *
     * @param string $password  Password to validate
     *
     * @return bool             Whether $password is valid or not.
     */
    function validate_password($password) {
        //If no alphabet characters found, return false.
        if (!preg_match("/[a-z]/i", $password)) {
            return false;
        }
        //If no digits found, return false.
        if (!preg_match("/[0-9]/", $password)) {
            return false;
        }
        //If a space is found, return false.
        if (strpos($password, " ") !== false) {
            return false;
        }
        //Special characters are optional, so no checking.
        //If nothing happened so far, the password is valid. Return true.
        return true;
    }
    
    var_dump(
        validate_password("test"),          //False, no digits
        validate_password("test123 test"),  //False, space
        validate_password("123456"),        //False, no alphabet
        validate_password("test1234")       //True
    );
    

    【讨论】:

    • +1 您还可以创建一个“阈值”以确保至少满足 4 个中的 3 个或其他什么...即,不要因任何一个失败而返回,而是计算有多少条件被满足。然后返回计数高于必要的阈值。
    【解决方案3】:

    使用三个单独的正则表达式 - 一个检查是否有字母字符,一个检查是否有数字,一个检查是否没有空格。虽然可以使用单个正则表达式完成所有这些操作,但每个附加条件都会显着增加正则表达式的复杂性。

    preg_match("/[a-z]/i", $passwd) && preg_match("/[0-9]/", $passwd) && !preg_match("/ /", $passwd)
    

    【讨论】:

      【解决方案4】:

      好像是这样的:

      ^(?=.*[0-9])(?=.*[a-zA-Z])(?=\S*$)(?=[0-9a-zA-Z.,;~!@#$%^&*()\-+=\\\]+$)
      

      添加您需要的所有特殊字符。

      编辑:回复一些cmets,下面是试运行的结果:

      <?php
      
      $re = '/^(?=.*[0-9])(?=.*[A-Z])(?=\S*$)(?=[0-9a-zA-Z.,;~!@#$%^&*()\-+=\\\]+$)/';
      
      $s = 'A2x.';
      
      echo preg_match($re, $s);
      
      ?>
      

      在 Ubuntu 下使用 CLI 测试:

      me@mymachine$ php _.php
      1
      

      根据$s 的值,它会得到01 ;)

      【讨论】:

      • 该正则表达式永远无法匹配,因为它包含两个行尾字符 ($)。
      • 而 m.buettner 的解决方案非常完美。点赞。
      • @duskwuff:你可以拥有任意数量的锚点,只要每个锚点都在自己的前瞻中。但是,(?=\S*$) 部分毫无意义。第四个前瞻枚举所有允许的字符,其中没有一个是空白字符。无需单独的前瞻来确保所有字符都是非空白字符。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      相关资源
      最近更新 更多