Mike Upjohn Mike Upjohn - 5 months ago 37
C# Question

Regex for a Complex Password

I've got this Regex as a data annotation on a password field in a C# .NET MVC project.

[RegularExpression("(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[*+\\/|!\"£$%^&*()#[\\]@~'?><,.=-_]).{6,}", ErrorMessage = "Password must be between 6 and 20 characters and contain one uppercase letter, one lowercase letter, one digit and one special character.")]

I want to make the following passwords invalid:-

  • Testing

  • Testing1

  • TesTinG123

The following would be valid:-

  • Testing1*

  • T&sting123*

  • %F&y5HD$S

I would like a minimum of 6 characters, with at least one uppercase, one lower case, one digit and one special character. I hope the above regex would do it, but it lets Testing12 and Tester12 through as valid passwords.

What can I change in the above to get what I am expecting? I assumed the above requires one uppercase, one lowercase, one numeric and one special character but obviously I am wrong?

Thanks in advance!


You forgot to escape ] properly (it is advised to even put it at the start of the character class so that in .NET it could be parsed as a literal ] - for the client side validation, it needs to be escaped even there) and remember that a hyphen inside a character class creates a range (e.g. [=-_]), so it must be put at the end/start of the character class or at the end to denote a literal -).


                                         ^^                             ^

Or, if you just want to require at least 1 char that is not alphanumeric, use


where [\W_] matches any char but a word char (i.e. [^\p{L}\p{N}_] or - on client side - [^a-zA-Z0-9_]) + _.

The ^ and $ anchors are redundant in the RegularExpressionAttribute pattern, but they won't do any harm.

See the regex demo.