2011-03-09 56 views
1

跟在PHP regular expression to match alpha-numeric strings with some (but not all) punctuation之后,我需要接受至少两种类型的字符,它们必须是数字,字母或标点符号中的一种,字符串必须介于6和18个字符。这是最好的方式吗?我使用RegExLib中的模式构造了这个正则表达式。PHP正则表达式:字符串必须包含字符类型

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

您的解决方案太复杂。只要检查字符类型和长度的存在。

<?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. 字母 - 数字
  2. 数字 - 信
  3. 信 - 标点
  4. 标点符号 - 信
  5. Digit - 标点符号
  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; 
} 

这是关于只要你的正则表达式,它更可读(恕我直言)...

+0

我测试了我的正则表达式所有三种类型,它仍然工作。前视也负责排序。但我看到你的更可读性和工作。 – nymo

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 
} 

注意,长度标准只需要进行一次检查。而且,到目前为止,它可能比其他任何解决方案都要快。

+0

为什么空格在密码中无效? – erenon

+0

用于检查长度的原始帖子的正则表达式字符类中不包含空格。但你说得对,这个问题的措辞没有明确说明。 – ridgerunner

1

这是它在一个正则表达式:

/^(?=.*[A-Za-z])(?=.*[0-9])([[email protected]#$%^&*-\[\]])+$/

让小资金数字和特殊字符 检查,如果密码至少包含一个字符和一个数字

相关问题