字符串的正则表达式,必须包含最少14个字符,其中至少2个是数字,最少6个是字母

时间:2011-04-03 02:32:46

标签: php javascript regex

我需要一个正则表达式来测试

的字符串
  • 最少14个字符 - 有效期为A-Za-z0-9#,.-_
  • 14个
  • 中至少6个字母
  • 该14
  • 中至少有2个数字

有没有办法可以将它包装在一个正则表达式中(目前我有一个javascript和php函数可以执行三个单独的测试,一个是14个,另一个是至少有两个数字,另一个是至少有6个字母。

所以以下内容是有效的:

  • blabla2bla2f54a(有效期>总共14个,至少6个字母,至少2个数字)
  • thisIsNotValidAtAll(因为少于2个数字而无效)

4 个答案:

答案 0 :(得分:15)

轻松!首先让我们看一下PHP中的注释版本:

$re = '/# Match 14+ char password with min 2 digits and 6 letters.
    ^                       # Anchor to start of string.
    (?=(?:.*?[A-Za-z]){6})  # minimum of 6 letters.
    (?=(?:.*?[0-9]){2})     # minimum of 2 numbers.
    [A-Za-z0-9#,.\-_]{14,}  # Match minimum of 14 characters.
    $                       # Anchor to end of string.
    /x';

以下是JavaScript版本:

var re = /^(?=(?:.*?[A-Za-z]){6})(?=(?:.*?[0-9]){2})[A-Za-z0-9#,.\-_]{14,}$/;

附录20121130:

我注意到这个答案最近得到了一个upvote。这使用了一个更过时的表达式,所以我认为是时候用更好的表达式更新它...

更有效的表达方式:

通过完全摆脱点星并贪婪地应用更精确的表达式(一个否定的char类),可以得到更有效的解决方案:

$re = '/# Match 14+ char password with min 2 digits and 6 letters.
    ^                              # Anchor to start of string.
    (?=(?:[^A-Za-z]*[A-Za-z]){6})  # minimum of 6 letters.
    (?=(?:[^0-9]*[0-9]){2})        # minimum of 2 numbers.
    [A-Za-z0-9#,.\-_]{14,}         # Match minimum of 14 characters.
    $                              # Anchor to end of string.
    /x';

以下是新的JavaScript版本:

var re = /^(?=(?:[^A-Za-z]*[A-Za-z]){6})(?=(?:[^0-9]*[0-9]){2})[A-Za-z0-9#,.\-_]{14,}$/;

修改:将#,.-_添加到有效字符列表中 修改:将贪婪变为懒惰的星星 编辑20121130:添加了替代版本,将lazy-dot-star替换为更精确的表达式的更有效贪婪应用程序。

答案 1 :(得分:5)

我会建议多次检查,为此写一个正则表达式会很难看。多次检查还可以让您了解未达到的标准。

$input = 'blabla2bla2f54a';
$errors=array();
if (!preg_match('/^[A-Za-z0-9#,.\-_]*$/', $input))
    $errors[] = 'Invalid characters';
if (strlen($input) < 14)
    $errors[] = 'Not long enough';
if (strlen(preg_replace('/[^0-9]/','',$input)) < 2)
    $errors[] = 'Not enough numbers';
if (strlen(preg_replace('/[^A-Za-z]/','',$input)) < 6)
    $errors[] = 'Not enough letters';

if (count($errors) > 0) //Didn't work
{
    echo implode($errors,'<BR/>');
}

答案 2 :(得分:2)

echo preg_match("/(?=.*[#,.-_])((?=.*\d{2,})(?=.*[a-zA-Z]{6,}).{14,})/", $string);

输出:

blabla2bla2f54a (1)
thisIsNotValidAtAll (0)

答案 3 :(得分:-1)

不,那是不可能的,因为实际上你想做三次单独的检查。您不能将它们包装在一个返回true或false的表达式中。问题是,你需要通过AND运算符进行两次相同的检查,这是不可能的。 但我们可以做的是构建一个超大尺寸的RegExp,它可以识别每种可能的情况。但是帽子类型的RegExp是没有意义的,因为在你的字符串上应用这个测试需要很长时间。 我建议你做三个独立的测试:

var result = string.replace(/[A-Za-z]{6}/, "").replace(/[0-9]{2}/, "").replace(/[A-Za-z0-9#,\.\-]{6}/, "").length == 0 ? true : false; // By shortening our sting we're saving time on later chained replacement methods