Regexp Java For Password Validation

Regexp Java for password validation

Try this:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$

Explanation:

^                 # start-of-string
(?=.*[0-9]) # a digit must occur at least once
(?=.*[a-z]) # a lower case letter must occur at least once
(?=.*[A-Z]) # an upper case letter must occur at least once
(?=.*[@#$%^&+=]) # a special character must occur at least once
(?=\S+$) # no whitespace allowed in the entire string
.{8,} # anything, at least eight places though
$ # end-of-string

It's easy to add, modify or remove individual rules, since every rule is an independent "module".

The (?=.*[xyz]) construct eats the entire string (.*) and backtracks to the first occurrence where [xyz] can match. It succeeds if [xyz] is found, it fails otherwise.

The alternative would be using a reluctant qualifier: (?=.*?[xyz]). For a password check, this will hardly make any difference, for much longer strings it could be the more efficient variant.

The most efficient variant (but hardest to read and maintain, therefore the most error-prone) would be (?=[^xyz]*[xyz]), of course. For a regex of this length and for this purpose, I would dis-recommend doing it that way, as it has no real benefits.

Password validation in Java using RegEx

I might not use a single regex pattern, but would instead use multiple checks. For example:

String password = "ABC123@";
int numChars = password.replaceAll("(?i)[^A-Z]+", "").length();
int numDigits = password.replaceAll("\\D+", "").length();
int numSpecial = password.replaceAll("[^!@#$%^&*()_+.-]", "").length();

if (numChars >=1 && numChars <= 6 && numDigits >= 1 && numDigits <= 10 &&
numSpecial <= 1) {
System.out.println("password is valid");
}
else {
System.out.println("password is invalid");
}

Using regex to validate password

I would use the following regex pattern to assert your requirements:

^(?!.*[^A-Za-z0-9])(?=.{10,}).*\\d.*\\d.*$

This pattern says to:

^                   from the start of the password
(?!.*[^A-Za-z0-9]) look ahead and assert that we do NOT see any non letters or digits
(?=.{10,}) look ahead and assert that password length be 10 or longer
.*\\d.*\\d.* then match any pattern so long as two digits be present
$ end of the password

I would probably just directly use String#matches here:

Scanner scan = new Scanner(System.in);
String password = scan.nextLine();
if (password.matches("(?!.*[^A-Za-z0-9])(?=.{10,}).*\\d.*\\d.*")) {
System.out.println("Password is valid");
}

Note that we drop the ^ and $ anchors from the regex pattern when using it with String#matches because this method implicitly applies the pattern to the entire string input.

Password validation using Java regex fails

You may use this regex with 2 lookahead assertions:

^(?=[^a-z]*[a-z])(?=[^!@#$%^&*()_+=?~]*[!@#$%^&*()_+=?~][^!@#$%^&*()_+=?~]*$).{12,}$

RegEx Demo

Note that in .matches() method start & end anchors are automatically implied in a given regex.

RegEx Details:

  • ^: Start
  • (?=[^a-z]*[a-z]): Positive lookahead to make sure we have at least one lowercase letter
  • (?=[^!@#$%^&*()_+=?~]*[!@#$%^&*()_+=?~][^!@#$%^&*()_+=?~]*$): Positive lookahead to make sure we have ONLY one of the given special character.
  • .{12,}: Match min 12 of any characters
  • $: End

Regex to validate password which accept only between fixed length

With the (?=.{10,16}) lookahead, you set the minimal length, 10, the ,16 is not important because you did not add $ at the end telling to stop matching after 16 chars are matched.

You may either add $ after {10,16}, or remove the lookahead and add {10,16} before the final $.

I suggest the one that follows the rule: the number of lookaheads must be number of conditions minus 1 (see rexegg.com for reference):

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&+=]).{10,16}$
^^^^ ^^^^^^^^

See the regex demo.

Details

  • ^ - start of string
  • (?=.*[0-9]) - at least one digit
  • (?=.*[a-z]) - at least one lowercase ASCII letter
  • (?=.*[A-Z]) - at least one uppecase ASCII letter
  • (?=.*[!@#$%^&+=]) - at least one of the special chars defined in the set
  • .{10,16} - any 10 to 16 chars
  • $ - end of string.

In Java, you do not need the leading ^ and trailing $ if you use the pattern in the .matches() method as it requires a full string match.

Java:

if (s.matches("(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&+=]).{10,16}")) {
return true;
}

Regex validate password with conditional statement Java

As per @kevin Esche comment you can test first two validation simply using .length() method of String.

In order for the password to be valid any 3 of the 4 validation rules you can use below code.

public static void main(String[] args) {
// TODO Auto-generated method stub
int count=0;
String password="a34A43";

boolean hasUppercase = !password.equals(password.toLowerCase());
boolean hasLowercase = !password.equals(password.toUpperCase());

if(hasUppercase)
count++;
if(hasLowercase)
count++;

Pattern p1 = Pattern.compile("[^a-z0-9 ]", Pattern.CASE_INSENSITIVE);
Matcher m = p1.matcher(password);
if(m.find())
count++;
Pattern p2 = Pattern.compile("\\d+", Pattern.CASE_INSENSITIVE);
Matcher m2 = p2.matcher(password);
if(m2.find())
count++;

if(count>=3)
System.out.println("Valid Password");
else
System.out.println("Invalid Password");
}


Related Topics



Leave a reply



Submit