代码之家  ›  专栏  ›  技术社区  ›  Jason

为什么使用regex的raddataform验证总是失败?

  •  1
  • Jason  · 技术社区  · 5 年前

    我正试图使用telerik的raddataform控件来显示一个简单的登录表单。我让它正确地验证电子邮件,但是当我尝试使用regex验证程序验证密码时,它总是失败的。我正在使用的regex已经在其他地方使用,没有问题。我使用的测试密码是“tested12”,应该通过。为了总结测试,字符串至少应该有一个大写字母、一个小写字母和一个数字。它应该至少有8个字符长。

    正则表达式为:

    ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})
    

    下面是我用来定义密码字段的JSON元数据:

    {
        name: 'password',
        displayName: 'Password',
        editor: 'Text',
        validators: [{ 
            name: 'RegEx',
            params: {
                'regEx': '^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})',
                errorMessage: 'Passwords must be at least 8 characters long and contain numbers, uppercase letters, and lowercase letters.'
            }
        }]
    }
    

    我认为这并不重要,但我在一个NativeScriptVue项目中使用了来自NativeScriptUI的控件。

    1 回复  |  直到 5 年前
        1
  •  1
  •   Wiktor Stribiżew    5 年前

    regex只包含lookaheads,这是一种非消耗模式,它只检查字符串中是否存在某些文本,但实际上它们不会移动regex索引,也不会将匹配的文本放入匹配值中。这里验证的regex必须 消费 整根绳子。

    最简单的方法是将长度检查lookahead转换为消费模式:

    'regEx': '^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{8,}'
                                                ^^^^^
    

    实际上,如果使用对比原则,可以创建更好的密码regexps:

    'regEx': '^(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z])(?=[^0-9]*[0-9]).{8,}'
    

    细节

    • ^ -字符串开头
    • (?=[^a-z]*[a-z]) -(在字符串开始处执行一次检查的正前视)在0+个字符(小写ASCII字母除外)之后,必须有小写ASCII字母
    • (?=[^A-Z]*[A-Z]) -(在字符串开始处执行一次检查的正前视)在除大写ASCII字母之外的0+个字符之后,必须有一个大写ASCII字母
    • (?=[^0-9]*[0-9]) -(在字符串开始处执行一次检查的正前视)在除数字之外的0+个字符之后,必须有一个数字
    • .{8,} -8个或更多字符,换行字符除外。