Regex match a strong password with two or more special characters

12,913

Solution 1

/^(?=(?:.*[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})

Solution 2

I'm not sure a single regexp is the way to go for this test.

Personally i'd implement it something like this: (treat as pseudo code, i haven't tested it)

function testPassword(pw) {
    var len = pw.length;
    if(len < 15) return false;
    if(pw.replace(/[a-z]/,'').length > len - 2) return false;
    if(pw.replace(/[A-Z]/,'').length > len - 2) return false;
    if(pw.replace(/[0-9]/,'').length > len - 2) return false;
    if(pw.replace(/[!@#$%^&*-]/,'').length > len - 2) return false;
    return true;
}
Share:
12,913
rwyland
Author by

rwyland

Engineer, Entrepreneur, Coffee and Beer geek, Auto Enthusiast, DIYer

Updated on June 27, 2022

Comments

  • rwyland
    rwyland almost 2 years

    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!

  • rwyland
    rwyland over 13 years
    Tested and confirmed with 100,000 randomly created passwords. You sir are a regex jedi, thanks!
  • rwyland
    rwyland over 13 years
    I like your thinking, but I need regex because it works across multiple languages, so easier code reuse was key for me.
  • rwyland
    rwyland about 13 years
    Would like to add that this regex works multi-platform, but if you use it in javascript it will NOT work in IE7 because of the lookahead issue in the javascript engine. link
  • Joe
    Joe over 11 years
    Why won't they let you delete comments??
  • jackhowa
    jackhowa over 2 years
    This answer is criminally low-voted. Indeed "You sir are a regex jedi, thanks!" @kennytm