Ramesh Kumar
Ramesh Kumar

Reputation: 355

Password validation by regex

System.out.println(Pattern.matches("[A-Z]{1,}[a-z]{1,}[0-9]{2,}[@#$%]+[ ]*", "DEFabc45$  "));

but it don't work When I pass string like passW@ord45. Mean I should not following regex order pattern written here.

Following are the conditions given bellow:

Write a function boolean isValidPassword (String password) A Password is valid if it satisfies following conditions:

  1. Length of the password must be more than 10 (without counting spaces).
  2. Password must contain at least one capital and one small alphabet
  3. Password must contain at least 2 digits and if it does not have 2 digits then see next condition.
  4. Password must contain at least one special character from the given set- {$, @, _, -, ., /}

Upvotes: 1

Views: 532

Answers (1)

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89557

You can use the method linked in @davide comment, so basically:

(?=(?: *\\S){10})(?=.*[a-z])(?=.*[A-Z])(?=.*[$@_./-]|.*[0-9].*[0-9])

However, using .* everywhere will produce a lot of backtracking (in particular .*[0-9].*[0-9]), so the way to prevent this is to be more explicit:

(?=(?: *\\S){10,})(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z])[^$@_./0-9-]*+(?:[$@_./-]|[0-9][^0-9]*[0-9])

About features used in these two patterns:

\\S is a shorthand character class: all that is not a white-space character

(?=...) is a zero-width assertion (a test) called lookahead, and means followed by. So with it you can test several assertions from the same position like this: (?=..)(?=..)(?=..)... since characters are not consumed.

*Note that in the second pattern, I have choosen to not use the lookahead because since there are no more rules, it's not important to consume characters or not.

So each lookahead contains a rule:

rule 1: at least 10 non-space characters

(?=
    (?: *\\S){10}  # a group with optional spaces and one non space character
                   # the group is repeated 10 times, so there are at least
                   # 10 characters that are not a space
)

rule 2a: a lowercase letter

(?=
    [^a-z]*    # zero or more characters that are not a lowercase letter
    [a-z]      # until a lowercase letter
)

rule 2B: an uppercase letter, (same as 2a but with A-Z)

rules 3 et 4 are combined in one subpattern that is not in a lookahead as explained:

[^$@_./0-9-]*+          # all that is not a digit or a special character
                        # Note: I have added a possessive quantifier make the whole
                        # pattern to fail faster if the next group fails 
(?: # two possibilities:
    [$@_./-]            # a special character
  |                  # OR
    [0-9][^0-9]*[0-9]   # two digits: a digit, other characters, an other digit 
) 

You can use these patterns as it with lookingAt since there is no need to anchor them at the end (according to your requirements) or with matches but you need to add .* at the end to reach the end of the string.

Upvotes: 1

Related Questions