Matching passwords with regular expression
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,}
source to share
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;
source to share
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!
source to share
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".
source to share
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/
source to share