Если вам нужно одно регулярное выражение, попробуйте:
(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*\W)
Краткое объяснение:
(?=.*[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
И я согласен с SilentGhost, \W
может быть немного шире. Я бы заменил его набором символов следующим образом: [-+_!@#$%^&*.,?]
(не стесняйтесь добавлять больше, конечно!)