What is the regex to make sure that a given string contains at least one character from each of the following categories.
Lowercase character
Uppercase character
Digit
Symbol
I know the patterns for individual sets namely [a-z]
, [A-Z]
, \d
and _|[^\w]
(I got them correct, didn't I?).
But how do I combine them to make sure that the string contains all of these in any order?
If you need one single regex, try:
(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*\W)
A short explanation:
(?=.*[a-z]) // use positive look ahead to see if at least one lower case letter exists
(?=.*[A-Z]) // use positive look ahead to see if at least one upper case letter exists
(?=.*\d) // use positive look ahead to see if at least one digit exists
(?=.*\W) // use positive look ahead to see if at least one non-word character exists
And I agree with SilentGhost, \W
might be a bit broad. I'd replace it with a character set like this: [-+_!@#$%^&*.,?]
(feel free to add more of course!)
Bart Kiers, your regex has a couple issues. The best way to do that is this:
(.*[a-z].*) // For lower cases
(.*[A-Z].*) // For upper cases
(.*\d.*) // For digits
(.*\W.*) // For symbols (non-word characters)
In this way you are searching no matter if at the beginning, at the end or at the middle. In your have I have a lot of troubles with complex passwords.
You can match those three groups separately, and make sure that they all present. Also, [^\w]
seems a bit too broad, but if that's what you want you might want to replace it with \W
.
\W
and [\W]
result in the same.
Bart Kiers solution is good but it misses rejecting strings having spaces and accepting strings having underscore (_
) as a symbol.
Improving on the Bart Kiers solution, here's the regex:
(?=.\d)(?=.[a-z])(?=.[A-Z])((?=.\W)|(?=.*_))^[^ ]+$
A short explanation:
(?=.*[a-z]) // use positive look ahead to see if at least one lower case letter exists
(?=.*[A-Z]) // use positive look ahead to see if at least one upper case letter exists
(?=.*\d) // use positive look ahead to see if at least one digit exists
(?=.*\W) // use positive look ahead to see if at least one non-word character exists
(?=.*_) // use positive look ahead to see if at least one underscore exists
| // The Logical OR operator
^[^ ]+$ // Reject the strings having spaces in them.
Side note: You can try test cases on a regex expression here.
Success story sharing
.+
into.*
? I couldn't come up with a test case that fails with.*
. Are they same in this context? "Zero or more characters" seems to be fine - just seeking confirmation..+
into.*
or even.{4,}
for that matter.(?=.*[_\W])
doesn't work regex101.com/r/jH9rK1/1^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*[&%$]).{6,}$