Matching passwords with regular expression

I am using java.util.regex.Pattern to match passwords that meet the following criteria:

  • At least 7 characters
  • Must consist of letters and numbers only
  • At least one letter and at least one number

I have 1 and 2, but I can't think of how to do it.

1 and 2 - [\\w]{7,}

Any ideas?

0


source to share


5 answers


You can use this. It mainly uses lookahead to achieve the third requirement.

(?=.*\d)(?=.*[a-zA-Z])\w{7,}

      

or Java string

"(?=.*\\d)(?=.*[a-zA-Z])\\w{7,}"

      

Explanation



"(?=" +         // Assert that the regex below can be matched, starting at this position (positive lookahead)
   "." +           // Match any single character
      "*" +           // Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
   "\\d" +          // Match a single digit 0..9
")" +
"(?=" +         // Assert that the regex below can be matched, starting at this position (positive lookahead)
   "." +           // Match any single character
      "*" +           // Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
"[a-zA-Z]" +       // Match a single character present in the list below
                     // A character in the range between "a" and "z"
                     // A character in the range between "A" and "Z"
")" +
"\\w" +          // Match a single character that is a "word character" (letters, digits, and underscores)
   "{7,}"          // Between 7 and unlimited times, as many times as possible, giving back as needed (greedy)

      

Edit

If you want to enable Unicode letter support use this

(?=.*\d)(?=.*\pL)[\pL\d]{7,}

      

+4


source


Doing this with Regex alone will very easily become confusing and very difficult to understand / read if you ever need to change the password credentials.

Instead, loop over the password and count the different types of characters, then do simple if checks.



Such as (unverified):

if (password.length() < 7) return false;
int countDigit = 0;
int countLetter = 0;
for (int i = 0; password.length(); i++) {
    if (Character.isDigit(password.charAt(i)) {
        countDigit++;
    }
    else if (Character.isLetter(password.charAt(i)) {
        countLetter++;
    }
}

if (countDigit == 0 || countLetter == 0) {
    return false;
}

return true;

      

+4


source


You don't need a character class to use \w

, it is a character class on its own. However, it also matches the underline, which you didn't mention. Therefore it is better to use a custom character class.

For "at least one" part, use the forward option:

/(?=.*\d)(?=.*[A-Za-z])[A-Za-z0-9]{7,}/

      

You may need to add additional screens for it to work with Java *.

* unfortunately I cannot help!

+1


source


It is possible to do this in a single regex, but I would not, as it would be difficult to maintain.

I would just do:

if (pass.matches("[a-zA-Z0-9]{7,}") &&
    pass.matches("[a-zA-Z]") &&
    pass.matches("\\d"))
{
    // password is OK
}

      

Then it becomes obvious how to apply additional restrictions to the password - they are simply added with additional sentences && ...

.

NB: I used it on purpose [a-z]

, not \w

because I'm not sure what happens with \w

if you use it in alternate locales where other characters can be considered "letters".

+1


source


I would add another regex to cover the 3rd criterion (you don't have to nail them all into one regex, but might want to combine them). I would go with somthing like^(?=.*\d)(?=.*[a-zA-Z])

http://www.mkyong.com/regular-expressions/10-java-regular-expression-examples-you-should-know/

0


source







All Articles