0

首先我是一个正则表达式的菜鸟,所以这可能会进一步优化,如果是这样,请告诉我该怎么做。无论如何,在阅读了几篇关于正则表达式的文章后,我写了一个小正则表达式来满足我的密码匹配需求:

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

我要做的是:它必须以大写字母开头,必须包含小写字母,必须至少包含一个数字,必须至少包含一个特殊字符,并且长度必须在 8-20 个字符之间。以上以某种方式起作用,但它不强制使用特殊字符(。似乎匹配任何字符,但我不知道如何将它与积极的前瞻一起使用)并且最小长度似乎是 10 而不是 8。我在做什么错误的?

PS:我正在使用http://gskinner.com/RegExr/进行测试。

4

3 回答 3

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 字符类,它可能看起来像这样:

^(?=.*[:lower:])(?=.*[:digit:])(?=.*[:punct:])[:upper:]+[[:alnum:][:punct:]]{7,19}$

或者使用Unicode 字符类,它可能看起来像这样:

^(?=.*[\p{Ll}])(?=.*\d)(?=.*[\p{P}\p{S}])[\p{Lu}]+[\p{L}\d\p{P}\p{S}]{7,19}$

注意:每个都考虑一组不同的“特殊字符”,因此它们与第一个模式不同。

于 2013-09-04T21:53:10.290 回答
0

以下应该有效:

^(?=.*[a-z])(?=.*[0-9])(?=.*[^a-zA-Z0-9])[A-Z].{7,19}$

我删除了,(?=.*[A-Z])因为必须以大写字符开头的要求已经涵盖了这一点。我(?=.*[^a-zA-Z0-9])为特殊字符添加了,仅当至少有一个字符不是字母或数字时才会匹配。我还稍微调整了长度检查,这里的第一步是删除+之后的,[A-Z]以便我们知道到目前为止已经匹配了一个字符,然后将其更改.{8,20}.{7,19}(如果我们只能匹配 7 到 19 个字符,我们已经匹配了 1)。

于 2013-09-04T21:49:19.457 回答
0

好吧,如果我有这样的要求,我会这样写——除了绝对不可能或不切实际的情况,我更喜欢分解复杂的正则表达式。请注意,这是特定于英语的,因此 Unicode 或 POSIX 字符类(如果支持)可能更有意义:

/^[A-Z]/ && /[a-z]/ && /[1-9]/ && /[whatever special]/ && ofCorrectLength(x)

也就是说,我会避免尝试一次合并所有规则。

于 2013-09-04T21:50:40.683 回答