用于密码验证的Regexp Java


109

我正在创建用于密码验证的正则表达式,以在Java应用程序中用作配置参数。

regexp是:

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

密码策略为:

  • 至少8个字符

  • 包含至少一位数字

  • 包含至少一个较低的Alpha字符和一个较高的Alpha字符

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

  • 不包含空格,制表符等。

我只缺少第5点。我无法进行正则表达式检查空间,制表符,回车等。

有人可以帮我吗?


3
密码规则不正确。请参阅参考-密码验证以获取更多信息。
ctwheels

Answers:


317

试试这个:

^(?=.*[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

由于每个规则都是独立的“模块”,因此添加,修改或删除单个规则很容易。

所述(?=.*[xyz])构建体吃整个字符串(.*)和回溯到第一次出现在那里[xyz]可以匹配。如果[xyz]找到则成功,否则失败。

替代方法是使用勉强的限定符:(?=.*?[xyz])。对于密码检查,这几乎没有什么区别,对于更长的字符串,这可能是更有效的变体。

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


15
@ Kerby82:在Java字符串中,必须转义反斜杠。尝试使用\\s。这是Java要求,而不是正则表达式要求。
Tomalak

1
@Allov只是这样考虑:未执行的所有操作都是可选的。只需删除您不想执行的检查即可。应该容易使解决方案适应您的需求。
Tomalak 2010年

3
此答案已添加到“通用验证任务”下的堆栈溢出正则表达式常见问题解答中
aliteralmind 2014年

1
@ shA.t是同一回事。我只尝试保留(?=...)模式,使其与其余表达式的设置匹配
。– Tomalak

2
@ shA.t是说“仅包含非空格字符”((?=\S+$))还是“不包含空格字符”((?!.*\s))是一个优先事项。使用更好的东西。:)
Tomalak

55

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

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

说明:

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

5
。{5,10}表示最少5个字符,最多10个字符。以防万一有人在寻找具体的解释。
2015年

@iabhi,我在找这个。谢谢。
阿克莎莎·斯里尼瓦斯

由于安全原因,我试图对存储在char数组而不是String中的密码实施Regex。但是如何将正则表达式应用于char数组?
AgentM '18年

13

先前给出的所有答案均使用相同(正确)的技术针对每个要求使用单独的前瞻。但是它们取决于实际将使用密码的后端,存在一些效率低下和潜在的大量错误。

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

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

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

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

通过将可变量词{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

仅当您确实要允许任何字符时才应使用点。否则,使用(否定的)字符类将您的正则表达式限制为仅真正允许的字符。尽管在这种情况下差别不大,但是在其他更合适的情况下不使用点是一个很好的习惯。我看到太多灾难性回溯的情况,因为开发人员太懒了,无法使用比点更合适的东西。

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

\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空格。如果不允许[\x21-\x7E]使用Unicode字符,则可以使用而不是\S匹配所有非空格或控制字符的ASCII字符。

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


9

您不应该使用过于复杂的Regex(如果可以避免使用它们),因为它们是

  • 难以阅读(至少对您自己以外的每个人)
  • 很难扩展
  • 难以调试

尽管使用许多小的正则表达式可能会降低性能开销,但上述几点很容易实现。

我会这样实现:

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

从安全角度来看,强行设置更长的密码,防止使用众所周知的密码(例如12345和pass = user)要好得多,而不是使密码变得超级复杂且难以记住。
Martin Rauscher

我喜欢上面的方法。谢谢你!
Thomas Lang

1

密码要求:

  • 系统可以支持的密码长度至少应为八(8)个字符。
  • 密码必须包含至少两个(2)组中的字符:字母,数字和特殊字符。

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

我测试了它并且有效


1

对于任何对每种字符的最低要求感兴趣的人,我建议对Tomalak可接受的答案进行以下扩展:

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

请注意,这是一个格式化字符串,而不是最终的正则表达式模式。只需用最少的出现次数替换%d即可:数字,小写字母,大写字母,非数字/字符和整个密码(分别)。出现最大的可能性不大(除非您希望最大为0,有效地拒绝任何此类字符),但也可以轻松添加这些字符。注意每种类型周围的额外分组,以便最小/最大约束允许非连续匹配。这为系统创造了奇迹,我们可以集中配置所需的每种类型的字符数量,然后让网站以及两个不同的移动平台获取该信息,以便根据上述格式字符串构造正则表达式模式。


1

这个检查每个特殊字符:

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

1

带参数的Java方法准备就绪

只需复制并粘贴并设置所需的参数即可。

如果您不需要模块,只需对其注释或添加“ if”(如我对特殊字符所做的操作)即可

//______________________________________________________________________________
/**
 * 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;
}        


0

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

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

[正则表达式演示]


0

简单的一个

(“ ^(?=。* [0-9])(?=。* [az])(?=。* [AZ])(?=。* [\\ W _])[\\ S] {8 ,10} $“)

  1. (?=任意值)->表示在所有输入字符串中都为正,并确保已写入此条件。sample(?=。* [0-9])->表示确保在所有字符串中写入一位数字。如果未写,则返回false

  2. (?!一切)->(反之亦然)意味着如果条件被写入,否定的前瞻性返回false

    close意义^(条件)(条件)(条件)(条件)[\ S] {8,10} $


虽然仅答案可以提供问题的解决方案,但是一些解释将大大提高答案的质量。
Nigel Ren

0
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. 首先将密码设置为字符串,然后创建整数集o。
  2. 然后通过for循环检查每个字符。
  3. 如果在字符串中找到数字,则n加5。然后跳转到下一个for循环。Character.isDigit(s.charAt(i))
  4. 此循环检查字符串中放置的所有字母。如果找到,则在n中再添加5。Character.isLetter(s.charAt(i))
  5. 现在,通过if条件检查整数n。如果n = 10为true,则字符串为字母数字,否则为非字母。

0

您也可以这样做。

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


0

正则表达式是-

^(?:(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*)[^\s]{8,}$
  1. 至少8位数字{8,}
  2. 至少一个数字(?=。* \ d)
  3. 至少一个小写字母(?=。* [az])
  4. 至少一个大写字母(?=。* [AZ])
  5. 至少一个特殊字符(?=。* [@ ## %% ^&+ =])
  6. 没有空格[^ \ s]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.