【问题标题】:PHP regular expression: string must contain to types of charactersPHP正则表达式:字符串必须包含字符类型
【发布时间】:2011-03-09 20:52:34
【问题描述】:

跟进PHP regular expression to match alpha-numeric strings with some (but not all) punctuation,对于长度必须在 6 到 18 个字符之间的字符串,我需要接受至少 2 种类型的字符,它们必须是数字、字母或标点符号之一。这是最好的方法吗?我使用来自RegExLib 的模式构建了这个正则表达式。

preg_match('@' .  
// one number and one letter  
'^(?=.*\d)(?=.*[a-zA-Z])[!-%\'-?A-~]{6,18}$' .  
// one number and one punctuation  
'|^(?=.*\d)(?=.*[!-%\'-/:-?\[-`{-~])[!-%\'-?A-~]{6,18}$' .  
// or one punctation and one  
'|^(?=.*[!-%\'-/:-?\[-`{-~])(?=.*[a-zA-Z])[!-%\'-?A-~]{6,18}$' .  
'@i', $pass, $matches);

【问题讨论】:

    标签: php regex


    【解决方案1】:

    您的解决方案太复杂了。只需检查 char 类型和长度是否存在。

    <?php
    $is_special = preg_match('/[+#!\?]/', $pass); //sample only
    $is_numeric = preg_match('/[0-9]/', $pass);
    $is_char = preg_match('/[a-zA-Z]/', $pass);
    
    if ($is_special + $is_numeric + $is_char < 2) {
        //fail
    }
    
    //+lenght check
    

    【讨论】:

      【解决方案2】:

      该正则表达式将不起作用,因为如果您输入所有三种类型,您将被拒绝。

      构建一个会非常冗长,因为您需要考虑所有组合的可能性:

      1. 字母 - 数字
      2. 数字 - 字母
      3. 字母 - 标点符号
      4. 标点 - 字母
      5. 数字 - 标点符号
      6. 标点符号 - 数字
      7. 字母 - 数字 - 标点符号
      8. 字母 - 标点 - 数字
      9. 数字 - 字母 - 标点符号
      10. 数字 - 标点 - 字母
      11. 标点 - 字母 - 数字
      12. 标点 - 数字 - 字母

      相反,我建议手动进行:

      function isValidString($string) {
          $count = 0;
          //Check for the existence of each type of character:
          if (preg_match('/\d/', $string)) {
              $count++;
          }
          if (preg_match('/[a-z]/i', $string)) {
              $count++;
          }
          if (preg_match('/[!-%\'-\/:-?\[-{-~]/', $string)) 
              $count++;
          }
          //Check the whole string
          $regex = '/^[a-z\d!-%\'-\/:-?\[-{-~]{6,18}$/';
          if ($count >= 2 && preg_match($regex, $string)) {
              return true;
          }
          return false;
      }
      

      它与您的正则表达式一样长,并且更具可读性(恕我直言)...

      【讨论】:

      • 我用所有三种类型测试了我的正则表达式,它仍然有效。前瞻也负责排序。但我看到你的更易读和更有效。
      【解决方案3】:

      erenon 的解决方案错误地允许使用空格。 (它需要在检查长度时添加对有效字符的检查)。 以下是我的做法:

      if (preg_match('&
          # Password with 6-18 chars from 2 of 3 types: (digits|letters|punct).
          ^                            # Anchor to string start.
          (?:                          # Non-capture group for alternatives.
            (?=.*?[0-9])               # Either a digit
            (?=.*?[a-zA-Z])            #   and a letter,
          | (?=.*?[0-9])               # Or a digit
            (?=.*?[!-%\'-/:-?[-`{-~])  #   and a punctuation,
          | (?=.*?[!-%\'-/:-?[-`{-~])  # Or a punctuation
            (?=.*?[a-zA-Z])            #   and a letter.
          )                            # End group of alternatives.
          [!-%\'-?A-~]{6,18}$          # Match between 6 and 18 valid chars.
          &x', $password)) {
          // Good password
      } else {
          // Bad password
      }
      

      请注意,长度标准只需要检查一次。此外,它可能比迄今为止的任何其他解决方案都快。

      【讨论】:

      • 为什么密码中的空格无效?
      • 用于检查长度的原始帖子的正则表达式字符类中不包含空格。但你是对的,问题的措辞中没有明确说明这一点。
      【解决方案4】:

      这是一个正则表达式:

      /^(?=.*[A-Za-z])(?=.*[0-9])([A-Za-z0-9_!@#$%^&amp;*-\[\]])+$/

      允许小写数字和特殊字符 检查密码是否至少包含一个字符和一个数字

      【讨论】:

        猜你喜欢
        • 2015-05-12
        • 2019-10-07
        • 2011-05-02
        • 2011-11-30
        • 2011-05-05
        • 2011-07-22
        • 2011-06-27
        • 1970-01-01
        • 2022-01-12
        相关资源
        最近更新 更多