Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 用于密码验证的正则表达式。我知道有很多信息,但我不能完全理解_Java_Regex - Fatal编程技术网

Java 用于密码验证的正则表达式。我知道有很多信息,但我不能完全理解

Java 用于密码验证的正则表达式。我知道有很多信息,但我不能完全理解,java,regex,Java,Regex,我的要求如下: 至少8个字符, 必须至少包含1个小写字母 必须至少包含1个大写字母 必须至少包含一个数字 必须至少包含以下集合之一:!@$%^&* 不得包含和或结束 最后一部分是让我绊倒的部分,我在谷歌上搜索了一堆,得出了: ^(?=.*[^a-zA-Z])(?=.*[a-z])(?=.*[A-Z])\S{8,}$ 但我相信,如果我理解这篇文章,它将允许所有特殊字符,因为\S。我不能那样。我还需要检查字符串是否包含and或end 目前我有这个。它能工作,但不优雅 package testing

我的要求如下:

至少8个字符, 必须至少包含1个小写字母 必须至少包含1个大写字母 必须至少包含一个数字 必须至少包含以下集合之一:!@$%^&* 不得包含和或结束 最后一部分是让我绊倒的部分,我在谷歌上搜索了一堆,得出了:

^(?=.*[^a-zA-Z])(?=.*[a-z])(?=.*[A-Z])\S{8,}$
但我相信,如果我理解这篇文章,它将允许所有特殊字符,因为\S。我不能那样。我还需要检查字符串是否包含and或end

目前我有这个。它能工作,但不优雅

package testing;

import java.util.Scanner;

public class PasswordTest {

public static void main(String args[]){
    System.out.println("Start");
    Scanner sc = new Scanner(System.in);
    boolean done = false;       
    while(!done){
        boolean size = false;
        boolean upper = false;
        boolean lower = false;
        boolean special = false;
        boolean andEnd = false;
        boolean numeric = false;
        String password = sc.nextLine();
        if(password.length()>=8){
            size=true;
        }
        for(int x = 0;x < password.length();x++){
            if(password.charAt(x)>= 65 && password.charAt(x)<=90){
                upper = true;
            }
            if(password.charAt(x)>= 97 && password.charAt(x)<=122){
                lower = true;
            }
            if(password.charAt(x)>= 48 && password.charAt(x)<=67){
                numeric = true;
            }
            if(password.charAt(x)>= 33 && password.charAt(x)<=42){
                special = true;
            }
        }
        if(!password.contains("and") && !password.contains("end")){
            andEnd = true;
        }
        if(!size){
            System.out.println("Password too short");
        }
        if(!upper){
            System.out.println("Password does not contain an uppercase character");
        }
        if(!lower){
            System.out.println("Password does not contain an lowercase character");
        }
        if(!numeric){
            System.out.println("Password does not contain a number");
        }
        if(!special){
            System.out.println("Password does not contain a Special character");
        }
        if(!andEnd){
            System.out.println("Password does contain 'and' or 'end'");
        }
        done = size && upper && lower && numeric && special&& andEnd;
        if(done){
            System.out.println("Valid "+password);
        }else{
            System.out.println("Invalid "+password);
        }
    }
    sc.close();
}
}

这对于单个正则表达式不是问题,相反,您应该单独验证每个条件,仅在适当时使用正则表达式

Check that it contains a lowercase letter /[a-z]/
Check that it contains an upper case letter /[A-Z]/
Check the length password.length()
等等

您希望使代码清晰易懂——单独检查每个条件可以做到这一点。您使用命名布尔值的方法是一个良好的开端,但实现是不正确的

编辑:我原本没有遵守拒绝某些特殊字符的要求。我在信中加了这个。明确测试将使更改和验证这些条件变得更容易

public static void main(String args[]){

    System.out.println("Start");
    String password = getPassword()
    System.out.println("Valid "+password);

}

public static String getPassword(){
    boolean done = false;       
    String passwordCandidate;
    while(!done){
       Scanner sc = new Scanner(System.in);
       passwordCandidate = sc.nextLine();
       List<String> validationErrors = validate(passwordCandidate);

       done = validationErrors.size() == 0;
       if(!done){
            System.out.println("Invalid "+passwordCandidate);
            for(String errMsg : validationErrors) {
                 System.out.println(errMsg);
             }
        }
    }
    sc.close();
    return passwordCandidate;
}

public static List<String> validate(String passwordCandidate){
    List<String> errMsgs = new ArrayList<String>();

    boolean size = passwordCandidate.length()>=8;
    boolean upper = passwordCandidate.matches(".*[A-Z].*");
    boolean lower = passwordCandidate.matches(".*[a-z].*");
    boolean requiredSpecial = passwordCandidate.matches(".*[!@#$%^&*].*");
    boolean andEnd = !passwordCandidate.matches(".*[ae]nd.*");
    boolean numeric = passwordCandidate.matches(".*[0-9].*");
    boolean forbiddenSpecial = !passwordCandidate.matches(".*[^a-zA-Z0-9!@#$%^&*].*");

    if(!size){
        errMsgs.add("Password too short");
    }
    if(!upper){
        errMsgs.add"Password does not contain an uppercase character");
    }
    if(!lower){
        errMsgs.add("Password does not contain an lowercase character");
    }
    if(!numeric){
        errMsgs.add("Password does not contain a number");
    }
    if(!requiredSpecial){
        errMsgs.add("Password does not contain a Special character");
    }
    if(!forbiddenSpecial){
        errMsgs.add("Password contains a forbidden character");
    }
    if(!andEnd){
        errMsgs.add("Password contains 'and' or 'end'");
    }
    return errMsgs

}

按照您描述密码的方式,您可以使用:

if (subjectString.matches("(?=.*[a-z])(?=[A-Z])(?=[0-9])(?!.*[ae]nd)(?=.*[!@#$%^&*])\\S{8,}")) {
    // It matched!
  } 
else {  // nah, it didn't match...  
     } 
对于允许的字符集,我建议使用比\S更具体的字符集。例如,如果您愿意只使用ASCII字符,而不是结尾的{8,},则可以使用[!-~]{8,},它允许任何可打印的ASCII字符 每个?=。。。是一种前瞻,它断言某些东西是可以匹配的。 这个是一个否定的前瞻,断言某些东西无法匹配。 参考文献


有无数类似的问题。您在发布前是否尝试过搜索功能?不能使用and和end?这是什么疯狂的要求呢?另请参见Randall Munroe关于密码复杂性的想法:这可以通过一个正则表达式轻松实现:参见我的评论。如果你真的想告诉用户出了什么问题,那么我同意,这不应该用一个正则表达式来完成。@SteveP:我并没有说用一个正则表达式不能解决这个问题,但这不是一个最好用一个正则表达式来解决的问题。matches方法需要正则表达式来描述整个字符串,因此,您需要填充所有这些正则表达式,如:..[A-Z]....[A-Z].*等。此外,您没有解决不允许使用[A-Za-z0-9!@$%^&*]以外的字符的要求。谢谢,很高兴这有帮助: