1

I'm trying to create a regex that allows the 4 main character types (lowercase, uppercase, alphanumeric, and special chars) with a minimum length of 8 and no more than 2 identical characters in a row.

I've tried searching for a potential solution and piecing together different regexes but no such luck! I was able to find this one on Owasp.org

^(?:(?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))(?!.*(.)\1{2,})[A-Za-z0-9!~<>,;:_=?*+#."&§%°()\|\[\]\-\$\^\@\/]{8,32}$

but it uses at least 3 out of the 4 different characters when I need all 4. I tried modifying it to require all 4 but I wasn't getting anywhere. If someone could please help me out I would greatly appreciate it!

Shawn T
  • 83
  • 1
  • 5
  • does it need to be a RegEx ? It would likely be easier to split the work between the format and the letter duplication – zfrisch Oct 11 '19 at 19:45

3 Answers3

0

Can you try the following?

var strongRegex = new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*])(?=.{8,})");

Explanations
RegEx            Description
(?=.*[a-z])      The string must contain at least 1 lowercase alphabetical character
(?=.*[A-Z])      The string must contain at least 1 uppercase alphabetical character
(?=.*[0-9])      The string must contain at least 1 numeric character
(?=.[!@#\$%\^&])    The string must contain at least one special character, but we are escaping reserved RegEx characters to avoid conflict
(?=.{8,})        The string must be eight characters or longer

or try with

(?=.{8,100}$)(([a-z0-9])(?!\2))+$ The regex checks for lookahead and rejects if 2 chars are together

var strongerRegex = new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*])(?=.{8,100}$)(([a-z0-9])(?!\2))+$");

reference

Dhananjai Pai
  • 5,914
  • 1
  • 10
  • 25
0

I think this might work from you (note: the approach was inspired by the solution to this SO question).

/^(?:([a-z0-9!~<>,;:_=?*+#."&§%°()|[\]$^@/-])(?!\1)){8,32}$/i

The regex basically breaks down like this:

// start the pattern at the beginning of the string
/^

    // create a "non-capturing group" to run the check in groups of two 
    // characters
    (?:

        // start the capture the first character in the pair
        (

            // Make sure that it is *ONLY* one of the following:
            //   - a letter
            //   - a number
            //   - one of the following special characters:
            //       !~<>,;:_=?*+#."&§%°()|[\]$^@/-
            [a-z0-9!~<>,;:_=?*+#."&§%°()|[\]$^@/-]

        // end the capture the first character in the pair
        )

        // start a negative lookahead to be sure that the next character
        // does not match whatever was captured by the first capture
        // group
        (?!\1)

    // end the negative lookahead 
    )

    // make sure that there are between 8 and 32 valid characters in the value
    {8,32}

// end the pattern at the end of the string and make it case-insensitive
// with the "i" flag
$/i
talemyn
  • 7,822
  • 4
  • 31
  • 52
0

You could use negative lookaheads based on contrast using a negated character class to match 0+ times not any of the listed, then match what is listed.

To match no more than 2 identical characters in a row, you could also use a negative lookahead with a capturing group and a backreference \1 to make sure there are not 3 of the same characters in a row.

^(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z])(?=[^0-9]*[0-9])(?=[^!~<>,;:_=?*+#."&§%°()|\[\]$^@\/-]*[!~<>,;:_=?*+#."&§%°()|\[\]$^@\/-])(?![a-zA-Z0-9!~<>,;:_=?*+#."&§%°()|\[\]$^@\/-]*([a-zA-Z0-9!~<>,;:_=?*+#."&§%°()|\[\]$^@\/-])\1\1)[a-zA-Z0-9!~<>,;:_=?*+#."&§%°()|\[\]$^@\/-]{8,}$
  • ^ Start of string
  • (?=[^a-z]*[a-z]) Assert a-z
  • (?=[^A-Z]*[A-Z]) Assert A-Z
  • (?=[^0-9]*[0-9]) Assert 0-9
  • (?= Assert a char that you would consider special
    • [^!~<>,;:_=?*+#."&§%°()|\[\]$^@\/-]*
    • [!~<>,;:_=?*+#."&§%°()|\[\]$^@\/-]
  • )
  • (?! Assert not 3 times an identical char from the character class in a row
    • [a-zA-Z0-9!~<>,;:_=?*+#."&§%°()|\[\]$^@\/-]*
    • ([a-zA-Z0-9!~<>,;:_=?*+#."&§%°()|\[\]$^@\/-])\1\1
  • )
  • [a-zA-Z0-9!~<>,;:_=?*+#."&§%°()|\[\]$^@\/-]{8,} Match any of the listed 8 or more times
  • $ End of string

Regex demo

The fourth bird
  • 154,723
  • 16
  • 55
  • 70