Reputation: 33
I have to provide a data annotation regex for a password that's specified as:
min 8 chars
min 1 upper
min 1 lower
min 1 numeric
min 1 special char which can ONLY be one of the following:$|~=[]'_-+@. (and the password can contain no other special chars besides these)
It's the exclusion of special characters which is giving me the headache.
I've come up with this but it just does not work:
"^.*(?=.{8,})(?=.*[a-z])(?=.*[A-Z])(?=.*[\d])**(?(?!.*[^$|~=[\]'_\-+@.])|([^\W\w])).*$**
It resolves everything I enter as invalid.
Whereas this (for the special chars) on its own does work:
"(?(?!.*[^$|~=[\]'_\-+@.])|([^\W\w])).*$"
and I know the first part works, so what am I missing to make them work together?
Alternatively, is there a much simpler way of achieving this?
(.NET environment)
Upvotes: 3
Views: 3056
Reputation: 44279
If you really want to do that in one regex pattern:
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$|~=[\]'[email protected]])[a-zA-Z0-9$|~=[\]'[email protected]]{8,}$
That should do the trick. We require, the lower case, upper case letter, digit and symbol with lookaheads. Note that in the character class, you need to move -
to the end or escape it. Otherwise it creates a character range you don't want. Then we use normal matching to ensure that there are only the allowed characters, and at least 8 of them.
However, it's usually a much better approach to do multiple tests. Run these patterns individually:
[a-z] // does the input contain a lower case letter?
[A-Z] // does the input contain an upper case letter?
\d // does the input contain a digit?
[$|~=[\]'[email protected]] // does the input contain one of the required symbols?
[^a-zA-Z0-9$|~=[\]'[email protected]] // are there invalid characters?
where the first 4 should return true
and the last one should return false
. In addition you can check input.Length >= 8
. This makes for much more readable code and will allow you to issue an appropriate error message about which condition is not fulfilled.
In fact, since the last pattern ensures that there are only the desired characters, we can simplify the "there has to be one symbol condition" to [^a-zA-Z0-9]
(in both approaches). But I'm not sure whether that makes things more or less readable.
Upvotes: 3