Reputation: 31
I need to match a password field using javascript with the following requirements:
I have a regex
var password = /^(?=.[0-9])(?=.[!@#$%^&])[a-zA-Z0-9!@#$%^&]{10,20}$/;
how can i solve this?
Upvotes: 0
Views: 4545
Reputation: 2176
based on your 5 things in your requirements this is exact pattern you need
^(?=.*[!@#$%^&])(?!.*(.).*\1.*\1)[^\s~,'.:;^|]{10,20}$
Upvotes: 0
Reputation: 58531
I would write separate rules (probably using regex for all of them - for consistency - unless performance is a great concern) that each relate directly to a rule on your list.
var pw = "asddfak@kjg";
/* Should be alpha numaric with at least one special character. */
console.log(null !== pw.match(/[@+#$]/));
/* no spaces to be allowed */
console.log(null !== pw.match(/^\S+$/));
/* should be minimum 10 char and max 20 chars. */
console.log(null !== pw.match(/^.{10,20}$/));
/* No repeate of char more than 2 times. */
console.log(null === pw.match(/(.)(.*\1){2}/));
/* ~,'.:;^| are not allowed */
console.log(null !== pw.match(/^[^~,'.:;^|]+$/));
Although it is possible to make the regex more concise, I think it is much more maintainable to make the rules more literal to your intent. If performance is a significant issue (usually not for this kind of thing) then I would avoid regex, and implement the rules using string methods.
/ // start regex pattern
[ // open character class
@+#$ // match one of these `special` characters
] // close character class
/ // end regex pattern
/ // start regex pattern
^ // start matched string
\S+ // one or more (`+`) not spaces (`\S`)
$ // end matched string
/ // end regex pattern
/ // start regex pattern
^ // start matched string
.{10,20} // between 10 and 20 of any character (`.`)
$ // end matched string
/ // end regex pattern
/ // start regex pattern
(.) // any character captured as group 1
(.*\1){2} // followed by zero or more of anything (`\.*`) and then the captured group 1 (`\1`) two times (`{2}`)
/ // end regex pattern
/ // start regex pattern
^ // start matched string
[ // open character class
^~,'.:;^| // not (`^`) one of these characters
]+ // close character class
$ // end matched string
/ // end regex pattern
p.s. you should keep a lot of comments with regex you use, because unlike books, they are much easier written than read
Upvotes: 1
Reputation: 8293
This should work:
/^(?=.*?[!@#$%^&])(?:([a-zA-Z0-9!@#$%^&])(?!.*?\1.*?\1)){10,20}$/
(if by repeat more than 2 times you mean the same character can't appear thrice)
Explanation:
1st condition: at the very beginning, we'll go through the whole string a first time until we find a special character, as soon as we have it, we stop, if we don't, it fails (Source): (?=.*?[!@#$%^&])
2nd condition: nothing to do, [a-zA-Z0-9!@#$%^&]
doesn't allow spaces anyway
3rd condition: quantifier: {10,20}
4th condition: the subtle one: as we get through the string, for each character captured, we check the it's not repeated twice more (same source): (?!.*?\1.*?\1)
5th condition: same as whitespaces
Upvotes: 0
Reputation: 5236
This might be the required regex
^(?=.*[!@#$%^&])(?!.*(.).*\1.*\1)[A-Za-z\d!@#$%^&|]{10,20}$
(?=.*[!@#$%^&])
ensures at least one occurrence of the listed characters.
(?!.*(.).*\1.*\1)
ensures no character is repeated more than twice.
[A-Za-z\d!@#$%^&|]{10,20}
matches 10-20 occurrence of characters from the character class.
Upvotes: 1