PHP正则表达式:字符串必须包含字符类型

时间:2011-03-09 20:52:34

标签: php regex

跟进PHP regular expression to match alpha-numeric strings with some (but not all) punctuation,我需要接受至少2种类型的字符,这些字符必须是数字,字母或标点符号之一,字符串的长度必须介于6到18个字符之间。这是最好的方法吗?我使用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);

4 个答案:

答案 0 :(得分:4)

你的解决方案太复杂了。只需检查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

答案 1 :(得分:1)

正则表达式不起作用,因为如果你提供所有三种类型,你将被拒绝。

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

  1. Letter - Digit
  2. 数字 - 信件
  3. 信件 - 标点符号
  4. 标点符号 - 信件
  5. 数字 - 标点符号
  6. 标点符号 - 数字
  7. 字母 - 数字 - 标点符号
  8. 信件 - 标点符号 - 数字
  9. 数字 - 字母 - 标点符号
  10. 数字 - 标点 - 信件
  11. 标点符号 - 字母 - 数字
  12. 标点符号 - 数字 - 字母
  13. 相反,我建议手动完成:

    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;
    }
    

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

答案 2 :(得分:1)

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
}

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

答案 3 :(得分:1)

这是一个正则表达式:

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

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