Home > other >  Underscore in regex not validating
Underscore in regex not validating

Time:10-06

How do I add underscore as a part of my regex string.

Here is my string that checks for uppercase, lowercase, numbers and special characters. The rest of the special characters work. Validation isn't working for underscores.

 @"^[^\s](?=(.*[A-Za-z]){1,})(?=(.*[\d]){1,})(?=(.*[\W]){1,})(?=(.*[!@#$%^&*()- =\[{\]};:<>|_.\\/?,\-`'""~]{1,})).*[^\s]$"

enter image description here

Any ideas?

Thanks

CodePudding user response:

This is the regex that AWS Cogito uses, it should apply to your situation:

@"^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[\^$*.\[\]{}\(\)?\-“!@#%&\/,><’:;|_~`])\S{8,99}$"

You can check regexes at http://regexstorm.net, it's faster than building your application everytime.

CodePudding user response:

I've approached it like this: I took your requirements and made them into separate positive lookaheads:

Check for:

  • uppercase (?=.*[A-Z])
  • lowercase (?=.*[a-z]) (note that I broke A-Z and a-z up into separate groups)
  • numbers (?=.*\d)
  • special characters (?=.*[!@#$%^&*()- =\[{\]};:<>|_.\\/?,\-`'""~])

You can then combine them in any order and I've combined them in the same order as I listed them above and anchored it with the beginning of the line using ^. Don't add any extra matches before, in-between or after the groups in your requirement that could cause the regex to enforce a certain ordering of the groups:

  • The lookahead for any non-word character \W makes it impossible to match Underscore1_ since it will only match on "anything other than a letter, digit or underscore" - which is all Underscore1_ contains.
  • The starting [^\s] (and ending [^\s]) that consumes one character is likely destroying a lot of good matches. Underscore1_ or _1scoreUnder shouldn't matter, but if you start with _ and consume it with [^\s] like you do, the later lookahead for a special character will fail (unless you have a second special character in the password).
@"^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[!@#$%^&*()- =\[{\]};:<>|_.\\/?,\-`'""~])"

If you have a minimum length requirement of, say, 7 characters, you could add .{7,}$ to the end of the regex. Without a minimum length, a password of one character from each group will be enough, and since there are 4 groups, a password with only 4 characters will pass this filter.

I see no point in putting an upper length limit into the regex. If the user interface has accepted a string that is thousands of characters long, then why reject it for being too long later? The length of what you store is probably going to be much smaller anyway since you'll be storing the bcrypt/scrypt/... encoded password.

Suggestion: Also add space (or even whitespaces) to the list of special characters.

CodePudding user response:

In you regexp add underscore in 3rd Capturing Group regex101

@"^[^\s](?=(.*[A-Za-z]){1,})(?=(.*[\d]){1,})(?=(.*[\W_]){1,})(?=(.*[!@#$%^&*()- =\[{\]};:<>|_.\\/?,\-`'""~]{1,})).*[^\s]$"
  • Related