I need to match a password field using javascript with the following requirements:
- Should be alpha numaric with at least one special character.
- no spaces to be allowed
- should be minimum 10 char and max 20 chars.
- No repeate of char more than 2 times.
- ~,'.:;^| are not allowed
I have a regex
var password = /^(?=.[0-9])(?=.[!@#$%^&])[a-zA-Z0-9!@#$%^&]{10,20}$/;
how can i solve this?
-
var password = /^(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]{10,20}$/;PHP– PHP2013年04月02日 09:36:30 +00:00Commented Apr 2, 2013 at 9:36
-
I wouldn't force such passwort constraints on the user. Here is a quite thorough analysis of password strengths: tech.dropbox.com/2012/04/…Gerald Schneider– Gerald Schneider2013年04月02日 09:43:04 +00:00Commented Apr 2, 2013 at 9:43
-
@SachinMalmanchi pls check whether my regex worked for youNaveed S– Naveed S2013年04月02日 11:05:46 +00:00Commented Apr 2, 2013 at 11:05
4 Answers 4
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.
4 Comments
(?=.*[!@#$%^&].*) as it's pretty bad regarding performance and the last .* is unnecessary. Still, with such small strings it doesn't really matter I guess.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.
The code
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.
Regex Explained
/ // 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
4 Comments
[^\s] can be replaced with \Sfalse. You should write a wrapper function, including my demo code, that accepts a password, and returns true for a valid password, or handles errors if it is invalid. You should inform the user which rule was broken if the password is invalid.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
based on your 5 things in your requirements this is exact pattern you need
^(?=.*[!@#$%^&])(?!.*(.).*1円.*1円)[^\s~,'.:;^|]{10,20}$