tags:

views:

475

answers:

2

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?

+1  A: 

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.

SilentGhost
Thanks. I wasn't aware of \W. Just looked it up to find that it matches Not Word. Is there any difference between \W and [\W]? Is [\W] just redundant?
Amarghosh
@Amarghosh, yes, `\W` and `[\W]` result in the same.
Bart Kiers
+6  A: 

If you need one single regex, try:

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*(_|[^\w])).+$

A short explanation:

^                  // the start of the string
(?=.*[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 underscore or non-word character exists
.+                 // gobble up the entire string
$                  // the end of the string

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
Thanks again Bart. I wasn't aware of positive look ahead.
Amarghosh
You're welcome Amarghosh.
Bart Kiers
What would happen if i change the last `.+` 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.
Amarghosh
@Amarghosh: in this case, it makes no difference. Because of the positive look-aheads, the string already contains at least 4 characters. So it makes no difference to change `.+` into `.*` or even `.{4,}` for that matter.
Bart Kiers