-4

Possible Duplicate:
Password validation regex

I need to do the password validation in javascript with the below policies. Will you please let me know the regular expression for this? I'm quite new to regular expressions.

  • Password should be 8 to 18 character long, and Password should meet at least 3 of the following conditions:
  • Password should have at least one lower case character(a-z)
  • Password should have at least one upper case character(a-z)
  • Password should have at least one numeric value(0-9)
  • Password should have a special character (i.e. @ . - _ # $ %)

Please help me out with this. I'm not able to determine how to provide a condition to meet this requirement.

Community
  • 1
  • 1
  • 4
    Have you tried anything and run into specific problems? Why do you need a single regex for this? – mu is too short Dec 31 '12 at 08:41
  • 1
    why don't you just check each of those one at a time. should be simple enough. – kennypu Dec 31 '12 at 08:43
  • 2
    This is asked very often here, and it's nearly a duplicate of [Password validation regex](http://stackoverflow.com/questions/5068843/password-validation-regex) and [Password strong - not require each condition](http://stackoverflow.com/questions/3798062/password-strong-not-require-each-condition). These two answers also show that a single regex is not really suitable for this. – Tim Pietzcker Dec 31 '12 at 08:45
  • Requirement "Password should meet at least 3 of the following conditions" makes it impossible to use only one regexp to check. Use 4 regexps with counter "how many fails", if counter > 2 then 'wrong password' – pstr Dec 31 '12 at 08:54
  • 1
    Thanks for the responses. After going through few threads, i understood as to why it can't be done with a single regexp. So i used 4 regexps to achieve it. – HarishHarris Dec 31 '12 at 09:08

1 Answers1

2

This answer is just to show how unreadable it is to do in one regular expression. Please consider other cleaner alternatives to write your code.

It can be done in 1 regular expression, but it is horrible:

^(?:(?=.*[a-z])(?=.*\d)(?=.*[^a-zA-Z0-9\x00-\x1f])|(?=.*[a-z])(?=.*[A-Z])(?=.*\d)|(?=.*[A-Z])(?=.*\d)(?=.*[^a-zA-Z0-9\x00-\x1f])|(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9\x00-\x1f])).{8,18}$

It can be shorten a bit, but still as ugly:

^(?:(?=.*\d)(?=.*[^a-zA-Z0-9\x00-\x1f])(?:(?=.*[a-z])|(?=.*[A-Z]))|(?=.*[a-z])(?=.*[A-Z])(?:(?=.*\d)|(?=.*[^a-zA-Z0-9\x00-\x1f]))).{8,18}$

There are 4 extra conditions as you have mentioned in the question, which corresponds to these fragments:

  • (?=.*\d): Look-ahead for a digit (0-9)
  • (?=.*[a-z]): Look-ahead for a lower case English alphabet (a-z)
  • (?=.*[A-Z]): Look-ahead for an upper case English alphabet (A-Z)
  • (?=.*[^a-zA-Z0-9\x00-\x1f]): Look-ahead for some character other than digits and English alphabet. Control characters are also excluded.

To the best of my knowledge, there is no mechanism in regular expression to say match 3 out of 4 conditions. So I have to enumerate all those conditions, which takes up the bulk of the regex.

.{8,18} just match 8-18 of any character. And the whole regex is anchored with ^ and $.

nhahtdh
  • 55,989
  • 15
  • 126
  • 162