1

Below is the regex which validates my passwords:

(((?=.*\\d{2,20})(?=.*[a-z]{2,20})(?=.*[A-Z]{3,20})(?=.*[@#$%!@@%&*?_~,-]{2,20})).{9,20}[^<>'\"])

Basically what I want is that it contains all above given characters in password. But it needs those characters in sequence e.g it validates 23aaAAA@!, but it does not validatea2@!AAAa.

5
  • I also have the Same problem. Commented Nov 26, 2015 at 9:48
  • 1
    This looks like an XY problem. Is there a reason you need to use a regex for this, instead of validating the password another way? Commented Nov 26, 2015 at 9:48
  • password is generated based on this regex.so we need to validate it based on that regex. Commented Nov 26, 2015 at 9:50
  • Would validating it against multiple regexes be an option? e.g. password.matches("[A-Z]") && password.matches("[a-z]") && password.matches("\d") && password.matches("[^A-Za-z\d]")? Commented Nov 26, 2015 at 10:13
  • @BasharatAli: you doesn't give any feedback, have you tried to simply insert the regex inline as this? (?=(?:.*[0-9]){2,20})(?=(?:.*[a-z]){2,20})(?=(?:.*[A-Z]){3,20})(?=(?:.*[@#$%!&*?_~,-]){2,20}).{9,20}[^<>'\"]. Commented Dec 1, 2015 at 12:10

2 Answers 2

2

Simply add nested capturing groups to keep the chars validation not strictly as a sequence. The regex can be also simplified as follow (without extra groups):

(?=(?:.*[0-9]){2,20})
(?=(?:.*[a-z]){2,20})
(?=(?:.*[A-Z]){3,20})
(?=(?:.*[@#$%!&*?_~,-]){2,20})
.{9,20}
[^<>'\"] # This matches also the newline char, i don't think you really want this...

In java use it as follows to match the :

String regex = "(?=(?:.*[0-9]){2,20})(?=(?:.*[a-z]){2,20})(?=(?:.*[A-Z]){3,20})(?=(?:.*[@#$%!&*?_~,-]){2,20}).{9,20}[^<>'\"]";
String password = "23aaA@AA!@X"; // This have to be 10 chars long at least, no newline

if (password.matches(regex))
    System.out.println("Success");
else
    System.out.println("Failure");

The regex requires a password with (all not strictly in sequence):

  • (?=(?:.*[0-9]){2,20}): 2 numbers
  • (?=(?:.*[a-z]){2,20}): 3 lowercase lettes
  • (?=(?:.*[A-Z]){3,20}): 3 uppercase letters
  • (?=(?:.*[@#$%!&*?_~,-]){2,20}): 2 of the symbols in the chars group
  • .{9,20}: Min length of 9 and max of 20
  • [^<>'\"]: One char that is not in (<,>,',") (NOTE: this matches also the newline)

So the min/max is actually 10/21 but the last statemente matches also the newline, so in the online regex demo, the visible chars will be between 9 and 20.

Regex online demo here

Sign up to request clarification or add additional context in comments.

3 Comments

Php is PCRE based so it will work as expected, i can't be sure for Asp.net (it works in C#). The spacing is allowed by the free spacing (?x) modifier (not available in java), but place the groups inline to fix
let me try if does not work than i will get back to stack
@BasharatAli: sorry for some reason i think you have to accomplish this in java, i really need to sleep :)
0

I would not try to build a single regexp, because nobody will ever be able to read nor change this expression ever again. It's to hard to understand.

"a2@!AAAa" will never validate because it needs 2 digits.

If you want a password, that contains a minmuum and maximum number of chars from a group. simply count them.

public class Constraint {

    private Pattern pattern;
    public String regexp = "";
    public int mincount=2;
    public int maxcount=6;

    public Constraint(String regexp, int mincount, int maxcount) {
        this.mincount=mincount;
        this.maxcount=maxcount;
        pattern = Pattern.compile(regexp);
    }

    public boolean fit(String str)
    {
        int count = str.length() - pattern.matcher(str).replaceAll("").length();
        return count >= mincount && count <= maxcount;
    }

    @Override
    public String toString() {
        return pattern.toString();
    }
}


public class Test {

    static Constraint[] constraints = new Constraint[] {
            new Constraint("[a-z]",2,20),
            new Constraint("[A-Z]",2,20),
            new Constraint("\\d",2,20),
            new Constraint("["+Pattern.quote("@#$%!@@%&*?_~,-")+"]",2,20),
            new Constraint("[<>'\\\"]",0,0)
    };

    public static boolean checkit(String pwd)
    {
        boolean ok=true;
        for (Constraint constraint:constraints)
        {
            if (constraint.fit(pwd)==false)
            {
                System.out.println("match failed for constraint "+constraint);
                ok=false;
            }
        }
        return ok;
    }

    public static void main(String[] args) {
        checkit("23aaAAA@!");
        checkit("a2@!AAAa");
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.