I can't think of a direct way to do this to be honest: regular expressions aren't very supportive of "must contain". What language are you writing this in? Personally, I'd do this by checking for each regular expression in turn and counting how many matches you get, so in python it would be something like this:
#!/usr/bin/python
import re
count = 0
mystring = "password"
regexp = re.compile(r'[A-Z]')
if regexp.search(mystring) is not None:
count += 1
regexp = re.compile(r'[a-z]')
if regexp.search(mystring) is not None:
count += 1
# etc
if count < 3:
print "Not enough character types"
You could also do this a bit more cleanly with:
#!/usr/bin/python
import re
regexpArray = [re.compile(r'[A-Z]'), re.compile(r'[a-z]'), re.compile(r'\d'), re.compile(r'[^A-Za-z0-9]')]
count = 0
for regexp in regexpArray:
if regexp.search(mystring) is not None:
count += 1
if count < 3:
print "Not enough character types"
Alternatively, you could have a very complicated regular expression with lots of options (in different orders) or one of the various password strength checkers that you'll be able to find with google.
Edit:
The python way to do this without regular expressions would be something like the following. I'm sure there's a .NET equivalent for this that would be much quicker than regular expression matching.
#!/usr/bin/python
import string
mystring = "password"
count = 0
for CharacterSet in [string.ascii_lowercase, string.ascii_uppercase, "0123456789", r'''!"£$%^&*()_+-=[]{};:'@#~,<.>/?\|''']:
# The following line adds 1 to count if there are any instances of
# any of the characters in CharacterSet present in mystring
count += 1 in [c in mystring for c in CharacterSet]
if count < 3:
print "Not enough character types"
There may be a better way of generating the list of symbols.