首先,我是正则表达式的总菜鸟,所以这可能会进一步优化,如果是这样,请告诉我该怎么做。无论如何,在阅读了几篇关于正则表达式的文章之后,我为密码匹配需求编写了一个小正则表达式:
(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(^[A-Z]+[a-z0-9]).{8,20}
我要做的是:它必须以大写字母开头,必须包含小写字母,必须包含至少一个必须至少包含特殊字符的数字,并且长度必须在8到20个字符之间。 上面的某种方式有效,但它不会强制特殊的字符(。似乎匹配任何字符,但我不知道如何使用它与积极的前瞻)和最小长度似乎是10而不是8.我在做什么错?
PS:我正在使用http://gskinner.com/RegExr/对此进行测试。
答案 0 :(得分:1)
让我们去除断言,只看你的基本模式:
(^[A-Z]+[a-z0-9]).{8,20}
这将匹配一个或多个大写拉丁字母,后跟一个小写拉丁字母或十进制数字,后跟任意字符的8到20。所以是的,至少这将需要10个字符,但它没有匹配的最大字符数(例如,它将在字符串的开头允许100个大写字母)。此外,由于没有结束锚($
),此模式将允许匹配的子字符串后面的任何尾随字符。
我推荐这样的模式:
^(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$])[A-Z]+[A-Za-z0-9!@#$]{7,19}$
其中!@#$
是您想要允许的任何特殊字符的占位符。如有必要,请不要忘记转义特殊字符(\
,]
,^
位于字符类的开头,-
位于中间位置。
使用POSIX character classes,它可能如下所示:
^(?=.*[:lower:])(?=.*[:digit:])(?=.*[:punct:])[:upper:]+[[:alnum:][:punct:]]{7,19}$
或使用Unicode character classes,它可能如下所示:
^(?=.*[\p{Ll}])(?=.*\d)(?=.*[\p{P}\p{S}])[\p{Lu}]+[\p{L}\d\p{P}\p{S}]{7,19}$
注意:每个都考虑了一组不同的“特殊字符”,因此它们与第一个模式不同。
答案 1 :(得分:0)
以下内容应该有效:
^(?=.*[a-z])(?=.*[0-9])(?=.*[^a-zA-Z0-9])[A-Z].{7,19}$
我删除了(?=.*[A-Z])
,因为必须以大写字符开头的要求已经涵盖了这一点。我为特殊字符添加了(?=.*[^a-zA-Z0-9])
,只有在至少有一个不是字母或数字的字符时才会匹配。我还调整了一点长度检查,这里的第一步是删除+
之后的[A-Z]
,以便我们知道到目前为止确切匹配了一个字符,然后更改{{1 } {}} .{8,20}
(如果我们已经匹配1,我们只能匹配7到19个字符)。
答案 2 :(得分:0)
好吧,如果我有这样的要求,这就是我写它的方式 - 除了绝对不可能或不实用的情况之外,我更喜欢打破复杂的正则表达式。请注意,这是特定于英语的,因此Unicode或POSIX字符类(如果支持)可能更有意义:
/^[A-Z]/ && /[a-z]/ && /[1-9]/ && /[whatever special]/ && ofCorrectLength(x)
也就是说,我会避免尝试同时纳入所有规则。