HansGruber HansGruber - 6 months ago 17
PHP Question

Regex for password grading

I'm working on a regular expression grading the quality of the used password. The idea is that a password is considered mediocre if it contains ONLY 1 uppercase character OR atleast 6 uppercase characters. The password itself should be atleast 8 characters long.

Desired behavior:

Aaaaaaaa -> match

AAAAAAaa -> match

AAaaaaaa -> no match

I tried something like this:

(?=.*[A-Z]{1,1}|(?=.*[A-Z]{6,})).{8,}


Which doesn't do the trick because it also matches on AAaaaaaa. The problem is the first positive lookahead which allows 2-5 uppercase characters but i couldn't figure out how to avoid that.

Answer

You should restrict the first lookahead to only require 1 uppercase letter in the whole string. Just define the full string pattern as any non-uppercase letter(s) followed with 1 uppercase one, and then any number of non-uppercase letter characters are allowed.

If you plan to require 6 uppercase letters at a row, use

/^(?=[^A-Z]*[A-Z][^A-Z]*$|.*[A-Z]{6,}).{8,}$/
     ^^^^^^^^^^^^^^^^^^^^

See this regex demo

If these 6 uppercase letters can be scattered around the string, use

/^(?=[^A-Z]*[A-Z][^A-Z]*$|(?:[^A-Z]*[A-Z]){6,}).{8,}$/
                          ^^^^^^^^^^^^^^^^^^^^ 

Where (?:[^A-Z]*[A-Z]){6,} searches for at least 6 occurrences of 0+ non-uppercase letter characters followed with an uppercase letter. See this regex demo.

If you need to support Unicode, add /u modifier at the end of the regex, and replace [A-Z] with \p{Lu}, [^A-Z] with \P{Lu}.

Also, it is recommended to use \A instead of ^ and \z instead of $ since it is password validation.