Regexp Java for password validation

I'm creating a regexp for password validation to be used in a Java application as a configuration parameter.

The regexp is:

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

The password policy is:

  • At least 8 chars

  • Contains at least one digit

  • Contains at least one lower alpha char and one upper alpha char

  • Contains at least one char within a set of special chars (@#%$^ etc.)

  • Does not contain space, tab, etc.

I’m missing just point 5. I'm not able to have the regexp check for space, tab, carriage return, etc.

Could anyone help me?

176846 次浏览

试试这个:

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

说明:

^                 # 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

It's easy to add, modify or remove individual rules, since every rule is an independent "module".

(?=.*[xyz])构造吃掉整个字符串(.*) ,并回溯到 [xyz]可以匹配的第一个匹配项。如果找到 [xyz],它将成功,否则将失败。

The alternative would be using a reluctant qualifier: (?=.*?[xyz]). For a password check, this will hardly make any difference, for much longer strings it could be the more efficient variant.

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

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

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));
}
}

解说:

  • 数字必须至少出现一次
  • 小写字母必须至少出现一次
  • 大写字母必须至少出现一次
  • 特殊字符必须至少出现一次
  • 在整个字符串中不允许使用空格
  • .{8,}至少8个字符

Password Requirement :

  • 在系统可以支持的情况下,密码的长度应该至少为8个字符。
  • 密码必须包含这些分组中至少两个(2)的字符: 字母、数字和特殊字符。

    ^.*(?=.{8,})(?=.*\d)(?=.*[a-zA-Z])|(?=.{8,})(?=.*\d)(?=.*[!@#$%^&])|(?=.{8,})(?=.*[a-zA-Z])(?=.*[!@#$%^&]).*$
    

I tested it and it works

我认为这也可以做到(作为一个更简单的模式) :

^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])[^\s]{8,}$

[正则表达式演示]

All the previously given answers use the same (correct) technique to use a separate lookahead for each requirement. But they contain a couple of inefficiencies and a potentially massive bug, depending on the back end that will actually use the password.

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

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

First of all, since Java supports \A and \z I prefer to use those to make sure the entire string is validated, independently of Pattern.MULTILINE. This doesn't affect performance, but avoids mistakes when regexes are recycled.

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

检查密码是否包含空格并检查其最小长度可以通过在简写 \S上放置可变量量词 {8,}来一次完成,\S限制允许的字符:

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

如果提供的密码确实包含一个空格,那么将执行所有的检查,只是最后的检查在该空格上失败。这可以通过用 \S代替所有的点来避免:

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

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

Since there's a good chance the initial tests will find an appropriate character in the first half of the password, a lazy quantifier can be more efficient:

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

但是现在真正重要的问题是: 没有一个答案提到这样一个事实,即最初的问题似乎是由用 ASCII 思考的人写的。但是在 Java 中字符串是 Unicode。密码中是否允许使用非 ASCII 字符?如果是,那么只是不允许使用 ASCII 空格,或者应该排除所有 Unicode 空格。

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

这就引出了下一个潜在的问题: 我们是否希望允许控制字符?编写正则表达式的第一步是精确地指定您想匹配的和不想匹配的。唯一100% 技术上正确的答案是,问题中的密码规范是模棱两可的,因为它没有说明是否允许某些范围的字符,如控制字符或非 ASCII 字符。

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

  • 很难读懂(至少对于除了你自己以外的所有人)
  • 很难延伸
  • hard to debug

虽然使用许多小型正则表达式可能会带来一些性能开销,但是上面的要点很容易超过它。

我会这样执行:

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;
}

对于那些对每种类型角色的最低要求感兴趣的人,我建议在 Tomalak 的公认答案基础上进行以下扩展:

^(?=(.*[0-9]){%d,})(?=(.*[a-z]){%d,})(?=(.*[A-Z]){%d,})(?=(.*[^0-9a-zA-Z]){%d,})(?=\S+$).{%d,}$

注意,这是一个格式化字符串,而不是最终的正则表达式模式。只需将% 1! 替换为: 数字、小写、大写、非数字/字符和整个密码(分别)。不太可能出现最大值(除非您希望最大值为0,从而有效地拒绝任何此类字符) ,但也可以很容易地添加这些字符。注意每个类型周围的额外分组,以便 min/max 约束允许非连续匹配。这为一个系统创造了奇迹,在这个系统中,我们可以集中配置我们需要的每种字符的数量,然后让网站和两个不同的移动平台获取这些信息,以便根据上面的格式化字符串构建正则表达式模式。

很简单

(“ ^ (? = . * [0-9])(? = . * [ A-Z ])(? = . * [ A-Z ])(? = . * [ W _ ])[ S ]{8,10} $”)

  1. (?= anything)-> 意味着所有输入字符串都是正向的,并确保写入了这个条件。样本(?=.* [0-9])-> 表示确保在所有字符串中写入一个数字 .

  2. (? ! anything)-> (反之亦然)意味着如果条件是 written返回 假的,则负向前看。

    close meaning ^(condition)(condition)(condition)(condition)[ S ]{8,10}$

String s=pwd;
int n=0;
for(int i=0;i<s.length();i++)
{
if((Character.isDigit(s.charAt(i))))
{
n=5;
break;
}
else
{


}
}
for(int i=0;i<s.length();i++)
{
if((Character.isLetter(s.charAt(i))))
{
n+=5;
break;
}
else
{


}


}


if(n==10)
{
out.print("Password format correct <b>Accepted</b><br>");


}
else
{
out.print("Password must be alphanumeric <b>Declined</b><br>");
}

说明:

  1. 首先将密码设置为字符串并创建整数 set o。
  2. 然后检查 for 循环中的每个字符。
  3. If it finds number in the string then the n add 5. Then jump to the 下一个 for loop. < em > Charter.isDigit (s.charAt (i))
  4. 这个循环检查放置在字符串中的任何字母。如果它找到,然后 在 n < em > trait. isLetters (s.charAt (i))中再添加5个
  5. 现在用 If 条件检查整数 n 给定的字符串是字母数字否则它就不是。

这个检查每个特殊字符:

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

Java 方法已经为您准备好了,带有参数

只需复制和粘贴,并设置所需的参数。

如果你不想要一个模块,只需要注释它或者添加一个“如果”,就像我对特殊字符所做的那样

//______________________________________________________________________________
/**
* Validation Password     */
//______________________________________________________________________________
private static boolean validation_Password(final String PASSWORD_Arg)    {
boolean result = false;
try {
if (PASSWORD_Arg!=null) {
//_________________________
//Parameteres
final String MIN_LENGHT="8";
final String MAX_LENGHT="20";
final boolean SPECIAL_CHAR_NEEDED=true;


//_________________________
//Modules
final String ONE_DIGIT = "(?=.*[0-9])";  //(?=.*[0-9]) a digit must occur at least once
final String LOWER_CASE = "(?=.*[a-z])";  //(?=.*[a-z]) a lower case letter must occur at least once
final String UPPER_CASE = "(?=.*[A-Z])";  //(?=.*[A-Z]) an upper case letter must occur at least once
final String NO_SPACE = "(?=\\S+$)";  //(?=\\S+$) no whitespace allowed in the entire string
//final String MIN_CHAR = ".{" + MIN_LENGHT + ",}";  //.{8,} at least 8 characters
final String MIN_MAX_CHAR = ".{" + MIN_LENGHT + "," + MAX_LENGHT + "}";  //.{5,10} represents minimum of 5 characters and maximum of 10 characters


final String SPECIAL_CHAR;
if (SPECIAL_CHAR_NEEDED==true) SPECIAL_CHAR= "(?=.*[@#$%^&+=])"; //(?=.*[@#$%^&+=]) a special character must occur at least once
else SPECIAL_CHAR="";
//_________________________
//Pattern
//String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}";
final String PATTERN = ONE_DIGIT + LOWER_CASE + UPPER_CASE + SPECIAL_CHAR + NO_SPACE + MIN_MAX_CHAR;
//_________________________
result = PASSWORD_Arg.matches(PATTERN);
//_________________________
}


} catch (Exception ex) {
result=false;
}


return result;
}

你也可以这样做。

 public boolean isPasswordValid(String password) {




String regExpn =
"^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}$";


CharSequence inputStr = password;


Pattern pattern = Pattern.compile(regExpn,Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(inputStr);


if(matcher.matches())
return true;
else
return false;
}

使用功能强大的 API 的 通行证库。

强密码的示例代码块:

(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?=\\S+$).{6,18}
  1. 至少6位数
  2. 最多18位
  3. 一个号码
  4. 一个小写字母
  5. 一个大写
  6. 可以包含所有特殊字符

RegEx 是..

^(?:(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*)[^\s]{8,}$
  1. 至少8位数字{8,}
  2. 至少一个数字(? = . * d)
  3. at least one lowercase (?=.*[a-z])
  4. 至少一个大写(? = . * [ A-Z ])
  5. 至少有一个特殊字符(? = . * [@# $% ^ & + = ])
  6. 没有空格[ ^ s ]

感谢所有的回答,基于所有这些,但扩展特殊字符:

@SuppressWarnings({"regexp", "RegExpUnexpectedAnchor", "RegExpRedundantEscape"})
String PASSWORD_SPECIAL_CHARS = "@#$%^`<>&+=\"!ºª·#~%&'¿¡€,:;*/+-.=_\\[\\]\\(\\)\\|\\_\\?\\\\";
int PASSWORD_MIN_SIZE = 8;
String PASSWORD_REGEXP = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[" + PASSWORD_SPECIAL_CHARS + "])(?=\\S+$).{"+PASSWORD_MIN_SIZE+",}$";

单位测试:

enter image description here

一个更一般的答案,接受 所有的特殊字符包括 _将略有不同:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[\W|\_])(?=\S+$).{8,}$

差异 (?=.*[\W|\_])转换为“包括下划线在内的所有特殊字符中的至少一个”。