确保字符串至少包含一个小写字母、大写字母、数字和符号的正则表达式

226
什么正则表达式可以确保给定的字符串至少包含以下每个类别中的一个字符。
  • 小写字符
  • 大写字符
  • 数字
  • 符号
我知道单个集合的模式,即[a-z][A-Z]\d_|[^\w](我理解正确了,对吗?)。
但是如何将它们组合起来以确保字符串包含所有这些字符,顺序并不重要?

什么平台/正则表达式方言?Bart的回答是正确的,但在JavaScript中,前瞻断言并不可靠。 - bobince
没有特定的地方 - 我正在学习正则表达式。在JavaScript中有没有可替代的方法? - Amarghosh
@bobince,你好,我正试图找出为什么在JavaScript中前瞻断言不可靠。有相关文章介绍吗? - Chris Bier
@ChrisB:有一个非常令人困惑的IE/JScript bug: http://blog.stevenlevithan.com/archives/regex-lookahead-bug - bobince
4个回答

458

如果你需要一个正则表达式,可以尝试:

(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*\W)

简短的解释:

(?=.*[a-z])        // use positive look ahead to see if at least one lower case letter exists
(?=.*[A-Z])        // use positive look ahead to see if at least one upper case letter exists
(?=.*\d)           // use positive look ahead to see if at least one digit exists
(?=.*\W)           // use positive look ahead to see if at least one non-word character exists

我同意SilentGhost的观点,\W可能有些宽泛。我会用像这样的字符集来代替它:[-+_!@#$%^&*.,?](当然您可以自由添加更多!)


1
@Amarghosh:在这种情况下,没有任何区别。由于正向前瞻,该字符串已经包含至少4个字符。因此,将.+更改为.*甚至是.{4,}都没有影响。 - Bart Kiers
如果您愿意添加一些解释,我很难理解这些前瞻的组合如何保证至少有一个字符集存在。 - Sharlike
@Sharlike,我不知道该如何重新表述以便更容易理解,特别是在这些小的评论框中。我建议你阅读这篇文章:http://www.regular-expressions.info/lookaround.html,如果你还有问题,可以发表自己的问题。祝你好运! - Bart Kiers
1
@BartKiers 如果我不想要任何符号怎么办?删除 (?=.*[_\W]) 无效。http://regex101.com/r/jH9rK1/1 - orloxx
7
请尝试将此正则表达式翻译为中文:^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*[&%$]).{6,}$该正则表达式要求密码必须包含至少一个小写字母、至少一个大写字母、至少一个数字,并且不能包含特殊字符&%$,长度必须为6位或以上。 - Bart Kiers
显示剩余8条评论

45

Bart Kiers,你的正则表达式有一些问题。最好的方法是这样的:

(.*[a-z].*)       // For lower cases
(.*[A-Z].*)       // For upper cases
(.*\d.*)          // For digits
(.*\W.*)          // For symbols (non-word characters)

这样,无论您是在开头、结尾还是中间搜索,都可以轻松搜到。我在您那里使用复杂密码时遇到了很多麻烦。


6
你没有按照原帖作者的要求检查符号。 - Janosh
6
只有在小写字母、大写字母和数字按照此顺序出现时,此方法才有效。例如,它不能处理111aaqBBB。 - gsouf

13
Bart Kiers的解决方案很好,但它错过了拒绝字符串中带有空格并接受具有下划线 (_) 作为符号的字符串。在改进Bart Kiers的解决方案后,这是正则表达式: (?=.*\d)(?=.*[a-z])(?=.*[A-Z])((?=.*\W)|(?=.*_))^[^ ]+$。简短的解释:
(?=.*[a-z])        // use positive look ahead to see if at least one lower case letter exists
(?=.*[A-Z])        // use positive look ahead to see if at least one upper case letter exists
(?=.*\d)           // use positive look ahead to see if at least one digit exists
(?=.*\W)           // use positive look ahead to see if at least one non-word character exists
(?=.*_)           // use positive look ahead to see if at least one underscore exists
|           // The Logical OR operator
^[^ ]+$           // Reject the strings having spaces in them.

顺带一提:你可以在这里尝试正则表达式的测试用例。


2
为什么要拒绝空格?如果是针对密码的话,根据OWASP建议,空格也应该包含在内。 - Janusz 'Ivellios' Kamieński
@Janusz'Ivellios'Kamieński 是的,你说得对。但是当时我创建的应用程序需要拒绝密码中的空格。无论如何,要允许空格,只需从正则表达式中删除此内容:^[^ ]+$ - Ensei_Tankado
1
明白了...只是顺便提一下 :) - Janusz 'Ivellios' Kamieński

6

您可以分别匹配这三个组,并确保它们全部出现。而且,[^\w]似乎太广泛了,但如果这是您想要的,您可能需要将其替换为\W


谢谢。我不知道\W。刚查了一下发现它匹配的是非单词字符。\W和[\W]之间有什么区别吗?[\W]只是多余的吗? - Amarghosh
@Amarghosh,是的,\W[\W] 的结果相同。 - Bart Kiers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接