tags:

views:

169

answers:

3

I'm trying for at least 2 letters, at least 2 non letters, and at least 6 characters in length:

^.*(?=.{6,})(?=[a-zA-Z]*){2,}(?=[0-9@#$%^&+=]*){2,}.*$

but that misses the mark on many levels, yet I'm not sure why. Any suggestions?

+2  A: 

If you really want to use regular expressions, try this one:

(?=.{6})(?=[^a-zA-Z]*[a-zA-Z][^a-zA-Z]*[a-zA-Z])(?=[^0-9@#$%^&+=]*[0-9@#$%^&+=][^0-9@#$%^&+=]*[0-9@#$%^&+=])^.+$

This matches anything that is at least six characters long ((?=.{6,})) and does contain at least two alphabetic characters ((?=[a-zA-Z][^a-zA-Z]*[a-zA-Z])) and does contain at least two characters of the character set [0-9@#$%^&+=] ((?=[0-9@#$%^&+=][^0-9@#$%^&+=]*[0-9@#$%^&+=])).

Gumbo
pts
But it’s less efficient because of unnecessary backtracking.
Gumbo
+10  A: 

While this type of test can be done with a regex, it may be easier and more maintainable to do a non-regex check. The regex to achieve this is fairly complex and a bit unreadable. But the code to run this test is fairly straight forward. For example take the following method as an implementation of your requirements (language C#)

public bool IsValid(string password) {
  // arg null check ommitted
  return password.Length >= 6 &&
         password.Where(Char.IsLetter).Count() > 2 &&
         password.Where(x => !Char.IsLetter(x)).Count() > 2;
}
JaredPar
Much clearer than any single regular expression that could do the same.
Bill the Lizard
I agree. While you might be able to crunch that down into a single line of regex, think of how long it would take you to do that as well as how long it would take you to change/debug it in the future.
Jason
There's no denying that a non-regex option would likely be better, but I'm tasked with "do as your told" --- I suspect this expression will be inserted into to a RegularExpressionValidator control on the web app. We have a saying here "It is what it is"
Ralph Shillington
@Ralph it really sucks when that happens. Is it possible for you to do multiple regex passes on the same string? That is very doable in 3 short concise regex's. One giant regex is just that giant. The number of permutations you have to try is huge.
JaredPar
+2  A: 
Alan Moore
Thanks for taking the time to not only spoon up a working RegEx, but to explain great detail what was wrong with the first one (which as you note is in fact the question)
Ralph Shillington