需要一些关于一些正则表达式验证的指针

时间:2013-08-27 20:37:55

标签: javascript regex

给定一个字符串,它必须具有以下内容:

  1. 只有一个号码
  2. (@#$ *)
  3. 中只有一个特殊字符
  4. 6个小写字母
  5. 该字符串可以是上述标准的任意组合,长度必须为8。

    示例:

    1. 2 @ QWERTY
    2. 1asddfg

    3. QWE * yt2u
    4. qw2wqia

    5. 到目前为止我的正则表达式:

      !/^(?=.*[0-9])(?=.*[^a-z])(?=.*[a-z])(?=.*[@#$*])\S{8,}$/.test(string)
      

      它适用于上述情况,但在以下情况下会中断:

      1. 2 @ 2qwert
      2. 2 @@ QWERT
      3. 我错过了什么?

5 个答案:

答案 0 :(得分:3)

  

我错过了什么?

您的测试'2 @ 2qwert'和'2 @@ qwert'与正则表达式错误匹配的原因是因为其中没有任何内容需要至少6个小写字母。根据对此问题的其他答案和评论,我要说使用(?=.*[a-z])替换您的(?=(.*?[a-z]){6})条款。

可以做出一些其他小改进:

  • 您可以删除多余的(?=.*[^a-z])子句,因为所有这一切都说该字符串应至少包含1个非字母,这已经由数字和特殊字符要求建立。
  • 用\ d。
  • 替换[0-9]
  • 在字符匹配(。*)之前匹配通配符的3个地方,如果这些非贪婪的话,它对RegExp引擎稍微快一些,这样在搜索字符串时回复就会减少一场比赛。这是通过放置一个?在*(。*?)之后。

根据你的正则表达式将它们放在一起:

/^(?=.*?\d)(?=(.*?[a-z]){6})(?=.*?[@#$*])\S{8,}$/

这成功匹配前4个字符串,但不是最后2个字符串。

(如果您需要可读的验证功能,我的原始回复如下。)

function validate(str)
{
  // test for digit
  if( !/\d/.test(str) ) return false;
  // test for special character
  if( !/[@#$*]/.test(str) ) return false;
  // test for 6 lowercase letters
  var letters = str.match(/[a-z]/g);
  return letters != null && letters.length == 6;
}

var tests = [ '2@qwerty', '#1asddfg', 'qwe*yt2u', '#qw2wqia', '2@2qwert', '2@@qwert' ];
for( var i=0 ; i<tests.length ; ++i )
  document.writeln(tests[i] + ": " + validate(tests[i]) + "<br/>\n");

答案 1 :(得分:3)

你的破裂案件应该破裂,因为他们不满足条件#3。话虽如此,我认为使用JavaScript和Regex的组合可能更容易:

function isValid(input) {
  return (input && input.length === 8)             /* make sure its 8 characters */
         && /[0-9]/.test(input)                    /* make sure it contains at least one digit */
         && /[@#$*]/.test(input)                   /* make sure it contains at least one special character */
         && /([^a-z]*[a-z]){6}.*/.test(input);     /* make sure it contains at least 6 lower case chars */ 
}

console.log(isValid('2@qwerty'));    // true
console.log(isValid('#1asddfg'));    // true
console.log(isValid('qwe*yt2u'));    // true
console.log(isValid('#qw2wqia'));    // true
console.log(isValid('2@2qwert'));    // false
console.log(isValid('2@@qwert'));    // false
console.log(isValid('2@qwerty'));   // now true as it satisfies #3

编辑:根据来自@Sniffer的输入更新了至少6个字符的检查(学习新内容很有趣,请参阅注释!)

答案 2 :(得分:2)

我想出了一个可能做你想要的正则表达式,但你可能不喜欢它的外观,但它背后的原理很简单:

^(?=^.{8}$)(?=\D*[0-9])(?=[^@#$*]*[@#$*])(?=([^a-z]*[a-z]){6})\S{8}$

此表达式首先确保只有8个字符(?=^.{8}$)

现在表达式检查是否只有一个号码(?=\D*[0-9]),然后确保有一个特殊符号(?=[^@#$*]*[@#$*])

现在表达式保证有6个小写字符(?=([^a-z]*[a-z]){6})

所以我们保证有一个数字,一个特殊符号和6个小写字符,总和是8个字符,所以字符串应该有效。

这当然不是最好的方法,因为您应该将此操作分解为多个步骤,但我想尝试使用单个表达式来实现它的乐趣,如果您发现任何问题请让我知道。

答案 3 :(得分:2)

描述

你的表达方式因为:

而中断
^(?=.*[0-9])(?=.*[^a-z])(?=.*[a-z])(?=.*[@#$*])\S{8,}$
            ^^^^^^^^^^^^                       ^^^^^^
  • [^a-z]是一个否定的字符类,因此这将匹配任何不是a-z的字符。我不确定这部分表达的目的是什么。
  • \S将匹配任何非空白字符。这允许使用字母,数字,unicode字符,换行符,任何符号......等等。
  • {8,}将允许8个或更多的前面字符。这允许字符串是无限长度。在您的帖子中,您希望字符串最多为8个字符。
  • 作为最佳实践,您应始终转义#,因为这可以在某些版本的正则表达式中用作注释字符,因此表达式已准备就绪,以防使用x选项。

我会像这样修改你的表达式:

  • 要求字符串有1个数字
  • 要求字符串包含1个@#$*符号
  • 要求字符串包含6个a-z小写字母(请务必不要使用不区分大小写的选项)
  • 要求字符串的全部长度为8个字符

^(?=.*?[0-9])(?=.*?[@\#$*])(?=(?:.*?[a-z]){6}).{8}$

Live Demo

enter image description here

NODE                     EXPLANATION
--------------------------------------------------------------------------------
  ^                        the beginning of the string
--------------------------------------------------------------------------------
  (?=                      look ahead to see if there is:
--------------------------------------------------------------------------------
    .*?                      any character except \n (0 or more times
                             (matching the least amount possible))
--------------------------------------------------------------------------------
    [0-9]                    any character of: '0' to '9'
--------------------------------------------------------------------------------
  )                        end of look-ahead
--------------------------------------------------------------------------------
  (?=                      look ahead to see if there is:
--------------------------------------------------------------------------------
    .*?                      any character except \n (0 or more times
                             (matching the least amount possible))
--------------------------------------------------------------------------------
    [@\#$*]                  any character of: '@', '\#', '$', '*'
--------------------------------------------------------------------------------
  )                        end of look-ahead
--------------------------------------------------------------------------------
  (?=                      look ahead to see if there is:
--------------------------------------------------------------------------------
    (?:                      group, but do not capture (6 times):
--------------------------------------------------------------------------------
      .*?                      any character except \n (0 or more
                               times (matching the least amount
                               possible))
--------------------------------------------------------------------------------
      [a-z]                    any character of: 'a' to 'z'
--------------------------------------------------------------------------------
    ){6}                     end of grouping
--------------------------------------------------------------------------------
  )                        end of look-ahead
--------------------------------------------------------------------------------
  .{8}                     any character except \n (8 times)
--------------------------------------------------------------------------------
  $                        before an optional \n, and the end of the
                           string

答案 4 :(得分:2)

这个正则表达式可以满足您的需求:

^(?=\D*\d\D*$)(?=[^@#$*]*[@#$*][^@#$*]*$)[@#$*\da-z]{8}$

它使用2个前瞻(锚定开始)来断言1个数字和1个特殊字符,以及所有有效字符的简单字符类(时间8)所以其余部分必须是小写的(不需要精确计数6)

在rubular上查看live demo个测试用例。