Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need some pointers on some regex validation

Given a string, it must have the following:

  1. only one number
  2. only one special character in (@#$*)
  3. 6 lower cased letters

The string can be in any combination of the above criteria and must be 8 in length.

Examples:

  1. 2@qwerty
  2. 1asddfg

  3. qwe*yt2u
  4. qw2wqia

Here my regex so far:

!/^(?=.*[0-9])(?=.*[^a-z])(?=.*[a-z])(?=.*[@#$*])\S{8,}$/.test(string)

It works for the above cases but breaks on cases like below:

  1. 2@2qwert
  2. 2@@qwert

What am I missing?

like image 841
iCodeLikeImDrunk Avatar asked Jun 18 '26 15:06

iCodeLikeImDrunk


1 Answers

What am I missing?

The reasons your tests '2@2qwert' and '2@@qwert' are incorrectly matching your regex is because there isn't anything in it that requires a minimum of 6 lowercase letters. Based on the other answers and comments to this question, I'd say replace your (?=.*[a-z]) clause with (?=(.*?[a-z]){6}).

Some other minor improvements that can be made:

  • You can drop the redundant (?=.*[^a-z]) clause since all this is saying is that the string should contain at least 1 non-letter, which is already established by the digit and special character requirement.
  • Replace [0-9] with \d.
  • In the 3 places where you are matching wildcards prior to a character match (.*), it is slightly faster for the RegExp engine if these are made non-greedy so that there is less backtracking done when searching through the string for a match. This is done by placing a ? after the * (.*?).

Putting this together based on your regexp:

/^(?=.*?\d)(?=(.*?[a-z]){6})(?=.*?[@#$*])\S{8,}$/

This successfully matches your first 4 strings, but not the last 2.

(My original response is below in case you want a readable validate function.)

function validate(str)
{
  // test for digit
  if( !/\d/.test(str) ) return false;
  // test for special character
  if( !/[@#$*]/.test(str) ) return false;
  // test for 6 lowercase letters
  var letters = str.match(/[a-z]/g);
  return letters != null && letters.length == 6;
}

var tests = [ '2@qwerty', '#1asddfg', 'qwe*yt2u', '#qw2wqia', '2@2qwert', '2@@qwert' ];
for( var i=0 ; i<tests.length ; ++i )
  document.writeln(tests[i] + ": " + validate(tests[i]) + "<br/>\n");
like image 169
Matt Avatar answered Jun 20 '26 03:06

Matt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!