Regex for Password validation first and last letter cannot have a symbol

I need a regexp for password validation. Validation rules-

  • Password is case sensitive
  • Must be no more than 50 characters long
  • Must include at least 1 number
  • Must have at least 1 symbol (non letter or number) character
  • The first character can not be a symbol (non letter or number)
  • The last character can not be a symbol (non letter or number)
  • Must not repeat any character sequentially more than 2 times
  • Must have at least 1 lowercase letter
  • Must have at least 1 uppercase letter
  • Must be at least 8 characters long

So far I have this -

 "^(?!.*(.)\\1{2})(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[^A-Za-z0-9]). 
        {8,50}$"

It doesn't work for the first and last character cannot be a symbol.

I have tried

^[a-zA-Z0-9](?!.*(.)\1{2})(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]).{6,48}[a-zA-Z0-9]$ 

but it is not working as well.Please help me out.

2 answers

  • answered 2018-08-09 00:52 Battle_Slug

    I think you need to change the approach. Your solution of having just one huge extensible regex doesn't conform Java. I'd suggest you think about building a library that can accept different rules and combine them. This will be much easier to test, it will be much more understandable for new people, less error-prone and easily extensible unlike the regex of the kind you are showing.

    This discussed here: Password strength checking library and suggested http://mvnrepository.com/artifact/edu.vt.middleware/vt-password

    Another option is here: https://github.com/larcki/validly So the code would look like that:

    import static com.validly.FailFastValidator.*;
    
    public class Validator {
    
        public void validate(String input) throws ValidationErrorException {
            valid(input)
                .mustNotBeNull("It's null")
                .lengthMustBeAtLeast(2, "It's too short")
                .mustStartWith("Hello", "It doesn't start properly")
                .must(s -> myOwnRule(s), "It doesn't match my own rule");
        }
    }
    

    Good luck!

  • answered 2018-08-09 04:20 Bohemian

    Each restriction can be a look ahead:

    ^(?=.*\d).{8,50}
    
    • (irrelevant) Password is case sensitive
    • .{8,50} Must be no more than 50 characters long and Must be at least 8 characters long
    • (?=.*\d) Must include at least 1 number
    • (?=.*(\W|_)) Must have at least 1 symbol (non letter or number) character
    • [^\W_] The first character can not be a symbol (non letter or number)
    • [^\W_] The last character can not be a symbol (non letter or number)
    • (?!.*(.)\1) Must not repeat any character sequentially more than 2 times
    • (?=.*[a-z]) Must have at least 1 lowercase letter
    • (?=.*[A-Z]) Must have at least 1 uppercase letter

    Putting it all together:

    ^(?!.*(.)\1)(?=.*\d)(?=.*(\W|_))(?=.*[a-z])(?=.*[A-Z])[^\W_].{6,48}[^\W_]$
    

    See live demo.