1

How can I construct a regular expression such that a password field I am making contains at least one number, at least one lowercase letter and at least one uppercase letter where order DOES NOT matter and anything can be in-between these characters?

I have tried this and got something similar: ".*\\d.*[a-z].*[A-Z].*" but that requires that the number comes first, the lowercase second and the uppercase last.

1

3 Answers 3

3

Yours is not one of the use case regular expressions are particularly good at – if you're stuck with regular expressions, I guess you have no choice but to enumerate the 6 cases:

.*[0-9].*[a-z].*[A-Z].*|.*[0-9].*[A-Z].*[a-z].*|.*[a-z] ... | ...

Check with actual java code would be easier (and more readable):

String  password = "";
boolean complies = password.matches(".*[0-9].*")
                && password.matches(".*[a-z].*")
                && password.matches(".*[A-Z].*");

or (uglier, but possibly faster):

boolean complies = false;
{
    boolean hasDigit     = false;
    boolean hasLowercase = false;
    boolean hasUppercase = false;
    for (int i = 0; i < password.length(); i++) {
        char c = password.charAt(i);
        hasDigit     |= '0' <= c && c <= '9';
        hasLowercase |= 'a' <= c && c <= 'z';
        hasUppercase |= 'A' <= c && c <= 'Z';
        if (hasDigit && hasLowercase && hasUppercase) {
            complies = true;
            break;
        }
    }
}
Sign up to request clarification or add additional context in comments.

7 Comments

Potentially stupid question, but what does the '?:' mean in front of the '.*' on your solution? I only use '.*' at the beginning of my attempt, is this incorrect?
(?: ... ) is a non-capturing group - I added those to group the alternatives (?:alt1)|(?:alt2) - honestly I didn't check if the whole thing works also without grouping (I tend to use more groups than needed)
Here's the doc about groups and capturing docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/…
Did a few tests - seems to work without groups too. Adding explicit grouping instead of relying on built-in precedence is just a habit of mine (not limited to regexes) personally I find 1+(5*4) clearer than 1+5*4. I'm removing the grouping above, sicne it's more confusing than useful :)
( ... ) is a capturing group, (?: ... ) is a non-capturing one - they are almost the same, the only difference is that capturing groups may be back-referenced, while non-capturing can't
|
3

One way to achieve this is by

1) First check for the presence of lower case letter by using a separate regex, say regex-1.

2) Next check if it contains numbers by using another regex.

3) Check for any other rule.

Breaking down the rules would solve the issue you are facing and also improves the way you report the error.

2 Comments

How would you do this though?
Have different Strings that hold the regex pattens-"\\d+", "[a-z]+", "[A-Z]+". Now for each pattern, compile and try matching with the password. You would know which regex pattern is failing. If none of them fail, it means the password has passed all the rules.
1

Regex is not suited for complicated scenarios like this. The only way you can implement it in regex is by listing all possibilities:

(abc|acb|bac|bca|cab|cba)

Where a, b, and c are sub-patterns that represent your individual requirements, e.g. abc would be .*\\d.*[a-z].*[A-Z].*, bac stands for [a-z].*.*\\d.*[A-Z].*, etc. Good luck in maintaining such a monster. My tip would be to create java constants for each of the parts:

private static final String DI = "\\d+";
private static final String LO = "[a-z]+";
private static final String UP = "[A-Z]+";
private static final String WI = ".*";
private static final String OR = "|";
private static final Pattern REGEX = Pattern .compile(
    WI + DI + WI + LO + WI + UP + WI + OR
  + WI + LO + WI + DI + WI + UP + WI + OR
  // etc
);

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.