Reputation: 533
I'm trying to create a regular expression that contains 17 characters, must have mandatory numbers and letters, and must not contain the letters I, O, Q, Ñ. At the moment I have got:
^(([a-h]|[j-n]|p|[r-z]|[A-H]|[J-N]|P|[R-Z]|[0-9]){17})$
But if I type only numbers or only letters, the regular expression validates it as good.
Upvotes: 1
Views: 263
Reputation: 700342
Use positive and negative look-aheads to require and disallow characters:
/^(?=.*[0-9])(?=.*[A-Za-z])(?!.*[ioqñIOQÑ])[0-9a-zA-Z]{17}$/.test(s);
Demo: http://jsfiddle.net/2mNyg/
Description:
(?=.*[0-9]) - requires a digit
(?=.*[A-Za-z]) - requires a letter
(?!.*[ioqñIOQÑ]) - disallows all characters in the set
[0-9a-zA-Z]{17} - allow basic set and require 17 characters
Note: The look-ahead that requires a letter will also be satisfied by the disallowed characters, but the look-ahead that disallows the characters will still stop it. That way you can make the expression simpler.
Upvotes: 3
Reputation: 437376
Generally in such cases you want to use positive lookahead in order to assert that the input satisfies additional conditions. Since you have two conditions here (must contain at least one number, must contain at least one letter), this translates to two different lookaheads.
Together with extra whitespace and "comments" for readability the regex should look like this:
^
(?=.*[a-hj-npr-zA-HJ-NPR-Z].*) // assert the input contains at least one letter
(?=.*[0-9].*) // assert the input contains at least one digit
[a-hj-npr-zA-HJ-NPR-Z0-9]{17} // existing condition (17 allowed chars exactly)
$
Upvotes: 4