4

Looking for some help for validating password with the following rules:

8+ characters

contains at least 1 upper case letter

contains at least 1 lower case letter

contains at least 1 number

Cannot start with a number

contains no special characters

I had gotten as far as:

(?=.*\d.*)(?=.*[a-z].*)(?=.*[A-Z].*)(?=.*[!#\$%&\?].*).{8,}

but can't seem to figure out how to get the first digit to not match a digit, and set the special character class to not match as well. Any help would be greatly appreciated.

2
  • 1
    just a remark, for beter password safety, it may be good to allow some special characters though, to make the spectrum of possibilities the widest possible Commented Jun 7, 2013 at 13:45
  • Our ERP systems doesn't allow special characters. Commented Jun 7, 2013 at 13:46

3 Answers 3

4

I find that breaking this down into individual tests is:

  • easier to code
  • easier to read
  • easier to maintain
  • and more flexible when requirements change

Try something like this:

var testPassword = function (password) {
    var minLengthMet = password.length >= 8,
        hasUpper = (/[A-Z]+/).test(password),
        hasLower = (/[a-z]+/).test(password),
        hasNumber = (/[0-9]+/).test(password),
        letterBegin = (/^[A-Za-z]/).test(password),
        noSpecials = !(/[^A-Za-z0-9]+/).test(password);
    return minLengthMet && hasUpper && hasLower && hasNumber && letterBegin && noSpecials;
};

See it in action here: http://jsfiddle.net/H9twa/

Sign up to request clarification or add additional context in comments.

3 Comments

great idea! just notes: [A-Za-z] is the same as \w, [0-9] is the same as \d, [^A-Za-z0-9] could be [^\w\d]
@JanTuroň, that's not 100% true Jan. \w also includes underscores. \w would be the same as [A-Za-z0-9_]
@JanTuroň: They are not the same. \w is the same as [A-Za-z0-9_]. You are correct about \d. Personally I prefer the character classes over the shorthand as I find them easier to read.
3

Here is what I would go with:

(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*[!#\$%&\?])^\D.{7}

Note that the .* after each look-ahead term was superfluous.

(?!...) is a negative look-ahead, to make sure there are no special characters.

^\D requires that the first character be a non-digit. Then I simply require 7 characters after that, because the end is not enforced.

But why exclude special characters from passwords? Usually just the opposite is encouraged.

2 Comments

As much as I admire the mastery of complex regexes, if I found something like this in the code I am working on I would seek out the author and send them a strongly-worded letter of complaint.
@MatthewGilliard, point taken. It is often better to break it into multiple steps. However, I don't think this one is really that complex if the code base uses a lot of regexes and everyone is familiar with them (and it is well-documented with a comment).
3

How about:

pwd.length >= 8 &&
pwd.match(/[A-Z]/) &&
pwd.match(/[a-z]/) &&
pwd.match(/\d/) &&
!pwd.match(/^\d/) &&
!pwd.match(/[!#\$%&\?]/);

Just in case you need to maintain this code ever?

1 Comment

Hardly any easier to maintain and takes more time to run. The regex solution is dead simple and if people don't understand regex then they still won't get what the values passed to the match method are anyway. I know good clean code is important but dumbing syntax for people who don't understand it seems overkill. Like writing a book in English so it can be read by the French.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.