Try this
^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).*$
See it here online on Regexr
The ^
and $
are anchors which bind the pattern to the start and the end of the string.
The (?=...)
are lookahead assertions. they check if the pattern after the =
is ahead but they don't match it. So to match something there needs to be a real pattern also. Here it is the .*
at the end.
The .*
would match the empty string also, but as soon as one of the lookaheads fail, the complete expression will fail.
For those who are concerned about the readability and maintainability, use the re.X
modifier to allow pretty and commented regexes:
reg = re.compile(r'''
^ # Match the start of the string
(?=.*[a-z]) # Check if there is a lowercase letter in the string
(?=.*[A-Z]) # Check if there is a uppercase letter in the string
(?=.*[0-9]) # Check if there is a digit in the string
.* # Match the string
$ # Match the end of the string
'''
, re.X) # eXtented option whitespace is not part of he pattern for better readability