Click here to Skip to main content
15,888,177 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I want to allow a password combination of eight characters with at least one special character, one alphabet, and one number. I want the RegEx suited for the same. I did the JavaScript validation using Regex, but the above combination (eight characters with at least one special character, one alphabet and one number) is not working.

What I have tried:

Code is as below:
JavaScript
var regex = /^(?=.*\d)(?=[^A-Za-z]*[A-Za-z])(?=.*[-!@#$%._]).{8,20}$"/
              
                //Validate TextBox value against the Regex.
                var isValid = regex.test(document.getElementById('<%=txtNewPass.ClientID %>').value);
                
                alert(isValid);
Posted
Updated 1-Feb-22 5:43am
v2

Quote:
I want to allow password combination of 8 characters with atleast one special character ,one alphabet and one number. I want the Regex suited for the same.

The answer is NO, a single RegEx is not able to check of those validations at once.
RegEx is not designed for this kind of validation as 1 RegEx.
All you can do is using 1 validation with a different RegEx for each aspect of validation.
 
Share this answer
 
It can be done, if you use positive lookahead assertions: Regex Tutorial - Lookahead and Lookbehind Zero-Length Assertions[^] but the resulting regex is pretty hard to work out, and even harder to modify.
Here's one for 8 characters, at least one special, at least one digit:
^(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]{8,}$
I'll let you work out how to add "at least one alpha" to that ... and you'll start to understand why it's a poor idea!

And anyway, password validation should be a server function, not client - since javascript is sent as part of the page text, it's very easy to circumvent client based checking via the browser console ...

To be honest, you'd probably be a lot better off using three separate matches and checking the counts all at the server: just because you can do something, doesn't mean you should!
 
Share this answer
 
I agree with the statements of the previous replies you probably shouldn't do this in a single regex. Doing it in multiple also allows you to show more specific error messages indicating what the problem is, instead of a long list of requirements the user then have to read through to figure out which one they are missing. This is how I recommend doing it.

And as mentioned in previous replies - always do the check on the server side, and optionally do it in JavaScript to provide instant feedback to the user.

That said, it is fairly simple to do it in a single regex, using "Lookahead Zero Length Assertions". OriginalGriff was very close in his answer, but did not quite reach the simplicity you can (or I missed something that prevents this approach from working).

The trick is to start the match with ^. This "anchors" everything you do at the start.
You then concatenate a lookahead zero length assertion for each rule you have. This works, as your zero length assertions do not move the position in the string. After each of them, the regex is still looking at the start of the string and can simply keep checking rules.
So we start with:
^

Add the rule it must be followed by at least 8 characters
^(?=.{8,})

Then add your special characters (you probably want more than these, this is just an illustration). Notice I prefix it with ".*". This skips over any non-special character so it no longer matters which position the special character is in. Remember to escape for JavaScript and Regex as needed (I was lazy and only chose characters where no escaping is needed).
^(?=.{8,})(?=.*[!#¤%&_-])

Now repeat this construct for alphabet (ignoring "lower/upper case" which you can trivially add, as well as the fact alphabet is language specific - i.e. why not accents or even Chinese characters - look into Regex character ranges for more information)
^(?=.{8,})(?=.*[!#¤%&_-])(?=.*[a-zA-Z])

Throw in the requirement for a digit:
^(?=.{8,})(?=.*[!#¤%&_-])(?=.*[a-zA-Z])(?=.*\d)


While the regex can looks a bit daunting, it is a very simple construct with each rule having it's own "top level parenthesis" - and no dependencies between the rules - so when you add/modify you do not need to go through all the other rules to make sure they still work. While the length increase for each rule, the complexity pretty much stays the same.

Make sure you add comments about how it is build up. Or maybe even better: Put each rule into a clearly named string, for example: minLength = "(?=.{8,)", and then build the final regex as "^" + minLenght + specialCharacter + atLeastOneDigit + ...
This will both keep the individual rules easy to read and "document" how the regex is build up. But it would also mean you could as well run the regexes one by one as originally suggested.

Notice the regex will not generate a match over the password. I.e. it will tell you the password is valid, but if you ask the regex how many characters it matched, it will say 0. If this is a problem, postfix your final regex with .*$, so it looks like this:
^(?=.{8,)(?=.*[!#¤%&_-])(?=.*[a-zA-Z])(?=.*\d).*$
 
Share this answer
 
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900