Regexp Java用于密码验证

Ker*_*y82 101 java regex

我正在为密码验证创建一个regexp,以便在Java应用程序中用作配置参数.

正则表达式是:

^.*(?=.{8,})(?=..*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$
Run Code Online (Sandbox Code Playgroud)

密码策略是:

  • 至少8个字符

  • 至少包含一位数字

  • 包含至少一个较低的alpha char和一个较高的alpha char

  • 在一组特殊字符中包含至少一个字符(@#%$^等)

  • 不包含空格,标签等

我只缺少第5点.我无法检查空格,制表符,回车等等的正则表达式.

谁能帮助我?

Tom*_*lak 288

试试这个:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$
Run Code Online (Sandbox Code Playgroud)

说明:

^                 # start-of-string
(?=.*[0-9])       # a digit must occur at least once
(?=.*[a-z])       # a lower case letter must occur at least once
(?=.*[A-Z])       # an upper case letter must occur at least once
(?=.*[@#$%^&+=])  # a special character must occur at least once
(?=\S+$)          # no whitespace allowed in the entire string
.{8,}             # anything, at least eight places though
$                 # end-of-string
Run Code Online (Sandbox Code Playgroud)

添加,修改或删除单个规则很容易,因为每个规则都是一个独立的"模块".

(?=.*[xyz])构造使用整个string(.*)并回溯到[xyz]可匹配的第一个匹配项.如果[xyz]找到则成功,否则失败.

替代方案是使用不情愿的限定符:(?=.*?[xyz]).对于密码检查,这几乎没有任何区别,对于更长的字符串,它可能是更有效的变体.

当然,最有效的变体(但最难阅读和维护,因此最容易出错)(?=[^xyz]*[xyz]).对于这个长度的正则表达式并且为了这个目的,我不建议这样做,因为它没有真正的好处.

  • @ Kerby82:在Java字符串中,必须转义反斜杠.尝试使用`\\ s`.这是Java要求,而不是正则表达式要求. (15认同)
  • 此答案已添加到[Stack Overflow Regular Expression FAQ](http://stackoverflow.com/a/22944075/2736496)的"Common Validation Tasks"下. (3认同)
  • @ shA.t你是否说"只包含非空格字符"(`(?=\S + $)`)或"不包含空格字符"(`(?!.*\s)`)是一个问题偏爱.使用你喜欢的任何东西.:) (2认同)

agi*_*les 51

使用正则表达式的简单示例

public class passwordvalidation {
    public static void main(String[] args) {
      String passwd = "aaZZa44@"; 
      String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}";
      System.out.println(passwd.matches(pattern));
   }
}
Run Code Online (Sandbox Code Playgroud)

说明:

  • (?=.*[0-9]) 一个数字必须至少出现一次
  • (?=.*[a-z]) 小写字母必须至少出现一次
  • (?=.*[A-Z]) 大写字母必须至少出现一次
  • (?=.*[@#$%^&+=]) 特殊角色必须至少出现一次
  • (?=\\S+$) 整个字符串中不允许有空格
  • .{8,} 至少8个字符

  • .{5,10}表示最少5个字符,最多10个字符.以防万一有人在寻找具体的解释. (4认同)

Jan*_*rts 11

所有先前给出的答案使用相同(正确)的技术为每个要求使用单独的先行.但它们包含一些低效率和潜在的大量错误,具体取决于实际使用密码的后端.

我将从接受的答案开始使用正则表达式:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$
Run Code Online (Sandbox Code Playgroud)

首先,由于Java支持\A并且\z我更喜欢使用它们以确保整个字符串被验证,独立于Pattern.MULTILINE.这不会影响性能,但可以避免在重复使用正则表达式时出错.

\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}\z
Run Code Online (Sandbox Code Playgroud)

检查密码不包含空格并检查其最小长度可以通过一次性使用all来完成,方法是将变量量词{8,}放在\S限制允许字符的速记上:

\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])\S{8,}\z
Run Code Online (Sandbox Code Playgroud)

如果提供的密码确实包含空格,则所有检查都将完成,只是最后一次检查失败.通过用以下代码替换所有点可以避免这种情况\S:

\A(?=\S*[0-9])(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[@#$%^&+=])\S{8,}\z
Run Code Online (Sandbox Code Playgroud)

只有在您真的想要允许任何角色时才应使用该点.否则,使用(否定的)字符类将正则表达式限制为仅允许真正允许的字符.虽然在这种情况下没有什么区别,但是当其他东西更合适时不使用圆点是一个非常好的习惯.我看到太多的灾难性回溯案例,因为开发人员懒得使用比点更合适的东西.

由于初始测试很有可能在密码的前半部分找到合适的字符,因此惰性量词可以更有效:

\A(?=\S*?[0-9])(?=\S*?[a-z])(?=\S*?[A-Z])(?=\S*?[@#$%^&+=])\S{8,}\z
Run Code Online (Sandbox Code Playgroud)

但是现在对于这个非常重要的问题:没有一个答案提到原始问题似乎是由一个用ASCII思考的人写的.但在Java中,字符串是Unicode.密码中是否允许使用非ASCII字符?如果是,则仅禁止ASCII空格,或者是否应排除所有Unicode空格.

默认情况下,\s仅匹配ASCII空格,因此其反向\S匹配所有Unicode字符(空白或非空白)和所有非空白ASCII字符.如果允许Unicode字符但不包含Unicode空格,则UNICODE_CHARACTER_CLASS可以指定该标志以\S排除Unicode空格.如果不允许[\x21-\x7E]使用Unicode字符,则可以使用它来代替\S匹配所有不是空格或控制字符的ASCII字符.

这将我们带到下一个潜在的问题:我们是否想要允许控制字符?编写正确的正则表达式的第一步是准确指定要匹配的内容和不匹配的内容.唯一100%技术上正确的答案是问题中的密码规范是不明确的,因为它没有说明是否允许某些字符范围如控制字符或非ASCII字符.


Mar*_*her 8

你不应该使用过于复杂的正则表达式(如果你能避免它们),因为它们是

  • 难以阅读(至少除了你自己以外的所有人)
  • 很难延伸
  • 很难调试

虽然使用许多小正则表达式可能会有很小的性能开销,但上面的点很容易超重.

我会这样实现:

bool matchesPolicy(pwd) {
    if (pwd.length < 8) return false;
    if (not pwd =~ /[0-9]/) return false;
    if (not pwd =~ /[a-z]/) return false;
    if (not pwd =~ /[A-Z]/) return false;
    if (not pwd =~ /[%@$^]/) return false;
    if (pwd =~ /\s/) return false;
    return true;
}
Run Code Online (Sandbox Code Playgroud)


sur*_*sea 5

感谢您的所有答案,基于所有答案,但扩展了特殊字符:

\n
@SuppressWarnings({"regexp", "RegExpUnexpectedAnchor", "RegExpRedundantEscape"})\nString PASSWORD_SPECIAL_CHARS = "@#$%^`<>&+=\\"!\xc2\xba\xc2\xaa\xc2\xb7#~%&\'\xc2\xbf\xc2\xa1\xe2\x82\xac,:;*/+-.=_\\\\[\\\\]\\\\(\\\\)\\\\|\\\\_\\\\?\\\\\\\\";\nint PASSWORD_MIN_SIZE = 8;\nString PASSWORD_REGEXP = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[" + PASSWORD_SPECIAL_CHARS + "])(?=\\\\S+$).{"+PASSWORD_MIN_SIZE+",}$";\n
Run Code Online (Sandbox Code Playgroud)\n

单元测试:

\n

在此输入图像描述

\n