tags:

views:

70

answers:

3

Hi,

I have the following criteria for creating a regular expression for a password that conforms to the following rules:

  1. The password must be 8 characters long (this I can do :-)).

The password must then contain characters from at least 3 of the following 4 rules:

  1. Upper case
  2. Lower case
  3. Numbers
  4. Non-alpha numeric

I can make the expression match ALL of those rules with the following expression:

/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.[\W]).{8,}$/

But I am struggling with how to do this in such a way that it only needs to solve any 3 of the 4 rules.

Can anyone help me out with this?

Thanks

Paul

+5  A: 

Don't use 1 regex to check it then.

if (password.length < 8)
  alert("bad password");
var hasUpperCase = /[A-Z]/.test(password);
var hasLowerCase = /[a-z]/.test(password);
var hasNumbers = /\d/.test(password);
var hasNonalphas = /\W/.test(password);
if (hasUpperCase + hasLowerCase + hasNumbers + hasNonalphas < 3)
  alert("bad password");

If you must use 1 regex:

^(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}$

(This regex is not optimized for efficiency.)

KennyTM
+1  A: 

You could write a really sophisticated regex to do that. Instead, I’d suggest writing four distinct regexes, one for each rule, and testing them one by one, counting how many of them matched. If three out of four did, accept the password.

Scytale
A: 

Id suggest doing the checks seperately, and then just totalling up how many match.

(I'd also not use a regex in any of them, but thats just my personal POV - namely that they hinder readability and are generally write-once code)

Visage