Regex javascript password

3

Good I have this pattern created

/^(?=.*[a-zñ])(?=.*[A-ZÑ])(?=.*[áéíóúÁÉIÓÚ])(?=.*\d){2,4}(?=.*[\$\/\.])[a-zA-ZáéíóúÁÉÍÓÚñÑ\$\/\.\d]{7,15}(?=.*\d$)/;

And I must control this: size 8,16, alphabetic characters 2 minimum, with a capital letter, with characters with accent, 4 max numbers and 2 min, must end in a number and mandatory characters such as $,., /, * ; #,!, ..

What have I got wrong?

    
asked by Ruth Mendez 13.02.2018 в 19:09
source

1 answer

5
  

What have I got wrong?

  • You are not controlling the maximum length:

    Let's eliminate the inspections (lookaheads), and let's see:

    [a-zA-ZáéíóúÁÉÍÓÚñÑ\$\/\.\d]{7,15}(?=.*\d$)
    

    The .* means that there can be any number of characters from the last repeated in the character class to the \d$ of the end.

    On the other hand, much simpler:

    [a-zA-ZáéíóúÁÉÍÓÚñÑ$/.\d]{7,15}\d$
    
    • No need to escape $ , * , / , . , etc. within a class (they have no special meaning there).
  • At least one upper case: you are not including accented capitalization in% (?=.*[A-ZÑ]) , but I guess it is intentional.

  • Contain a character with an accent. In (?=.*[áéíóúÁÉIÓÚ]) you missed the accent in Í (and I guess üÜ do not go).

  • 4 digits maximum and at least 2 ... This is an important error for you to understand. You are using:

    (?=.*\d){2,4}
    

    But keep in mind that in an inspection ( lookaround ), after trying the match, the cursor returns to the position it was before trying (in this case at the beginning of the string) . When an inspection is repeated, in fact, you are asking (2 to 4 times) if there is 1 digit from the beginning of the string ...

    If it was not understood:

    • There is 1 digit from the beginning of the string ... Yes
    • There is 1 digit from the beginning of the string ... Yes
    • There is 1 digit from the beginning of the string ... Yes
    • There is 1 digit from the beginning of the string ... Yes -Déjà vu: -)

    At no time are you seeing if there are 2 to 4 digits in the whole string.

    To see that there are only between 2 and 4, we have to repeat it in the inspection:

    ^(?=(?:\D*\d){2,4}$)
    
  • The condition " alphabetic characters (at least 2) " is not being checked anywhere. It would be:

    ^(?=(?:[^A-Za-záéíóúüÁÉÍÓÚÜñÑ]*[A-Za-záéíóúüÁÉÍÓÚÜñÑ]){2})
    
  • You used (?=.*[a-zñ]) but did not mention that you had to have a lowercase in your rules.


  • In short:

    /^(?=(?:[^A-Za-záéíóúüÁÉÍÓÚÜñÑ]*[A-Za-záéíóúüÁÉÍÓÚÜñÑ]){2})(?=.*[A-ZÑ])(?=.*[áéíóúÁÉÍÓÚ])(?=(?:\D*\d){2,4}$)(?=.*[$/.])[a-zA-ZáéíóúÁÉÍÓÚñÑ$/.\d]{7,15}\d$/
    


    Simplify

    But let's go deeper. On the one hand you said:

  • One capital + one accented letter.
  • And also:

  • 2 alphabetic characters
  • There is no way to meet the first and not the second. If it has a capital letter and 1 accented letter, it obviously has 2 alphabetic characters ... we can eliminate a condition:

    /^(?=.*[A-ZÑ])(?=.*[áéíóúÁÉÍÓÚ])(?=(?:\D*\d){2,4}$)(?=.*[$/.])[a-zA-ZáéíóúÁÉÍÓÚñÑ$/.\d]{7,15}\d$/
    


    And we know that it has to end with 1 digit, we are already controlling it in

    ^(?=(?:\D*\d){2,4}$)
    

    We can eliminate the condition of \d$ at the end

    /^(?=.*[A-ZÑ])(?=.*[áéíóúÁÉÍÓÚ])(?=(?:\D*\d){2,4}$)(?=.*[$/.])[a-zA-ZáéíóúÁÉÍÓÚñÑ$/.\d]{8,16}$/
    


    Demo:

    input { width: 30ch;  padding: 0.5em 1ch; border: 5px solid red;  }
    input:valid { border: 5px solid green;  }
    <input pattern="(?=.*[A-ZÑ])(?=.*[áéíóúÁÉÍÓÚ])(?=(?:\D*\d){2,4}$)(?=.*[$/.])[a-zA-ZáéíóúÁÉÍÓÚñÑ$/.\d]{8,16}"
            placeholder="Validación de contraseña"
            required>
        
    answered by 13.02.2018 / 19:39
    source