Search code examples
javascriptregexpasswords

Regex match a strong password with two or more special characters


I need to regex match a password field using javascript with the following requirements:

  • At least 15 characters
  • two or more lower case letters
  • two or more upper case letters
  • two or more digits
  • two or more of the following special characters: !@#$%^&*-

I have a regex that takes care of MOST cases:

/^.*(?=.{15,})(?=.{2,}\d)(?=.{2,}[a-z])(?=.{2,}[A-Z])(?=.{2,}[\!\@\#\$\%\^\&\*\-]).*$/

The problem here is with the symbols, it works with:

P@ssw0rdP@ssw0rd
Pssw0rdPssw0rd@@
Pssw0rd@@Pssw0rd

But not:

@@Pssw0rdPssw0rd

I have a random password generator set up to exhaustively test this, so any ideas are greatly appreciated. Thanks!


Solution

  • /^(?=(?:.*[a-z]){2})(?=(?:.*[A-Z]){2})(?=(?:.*\d){2})(?=(?:.*[!@#$%^&*-]){2}).{15,}$/
    

    Your lookaheads are wrong. The pattern

    (?=.{2,}[class])
    

    means to match 2 or more characters (no matter what characters), then followed by 1 character of the desired class. This is entirely different from "2 or more character of the desired class" you specified.

    To correctly test if a character of desired class is in the text, use

    (?=.*[class])
    

    and since you want to check it twice, repeat the pattern

    (?=.*[class].*[class])
    # equivalent to (?=(?:.*[class]){2})