Regex para contraseña Restricción de caracteres especiales

Estoy intentando tener algunas inputs de contraseña en las templates de formación en la nube de AWS. Y para restringir la contraseña a caracteres alfanuméricos y un subset de caracteres especiales. Intenté lo siguiente:

"^(?=.*?[AZ])(?=.*?[az])(?=.*?[0-9])(?=.*?[#@$?]).{8,}$" 

Esto informa que debe haber al less una mayúscula y una minúscula junto con un dígito numérico. Además, restringe el set de caracteres especiales a [#@$?]

Lo que observé fue que cualquier personaje especial si era el último estaba permitido. En cualquier otro lugar no fue permitido como se esperaba

Por lo tanto, Hello*E1 no está permitido, pero se permitió HelloE1* .

¿Cómo deshabilito todos los caracteres especiales excepto [#@$?] Sin importar dónde aparecen?

Además, ¿cómo no permitir todo el juego de caracteres especial? "^(?=.*?[AZ])(?=.*?[az])(?=.*?[0-9]).{8,}$ no ayudó. Esto permitió que todos los caracteres especiales .

Cualquier ayuda es apreciada.

Regex:

 ^(?=[a-zA-Z0-9#@$?]{8,}$)(?=.*?[az])(?=.*?[AZ])(?=.*?[0-9]).* 

Explicación:

En la expresión regular que proporcionó, el lookaheads sirve para garantizar que su cadena cumpla con algunas condiciones específicas, pero no son el filter real que evita cadenas no deseadas. Usted especificó las siguientes condiciones:

  • (?=.*?[AZ]) : Coincide al less con una letra mayúscula.
  • (?=.*?[az]) : coincide con al less una letra minúscula.
  • (?=.*?[0-9]) : unir al less un número.
  • (?=.*?[#@$?]) : Unir al less uno de estos caracteres: #@$?
  • .{8,} : unir cualquier personaje al less 8 veces.

Pero hay al less dos defectos:

  • La parte (?=.*?[#@$?]) es necesaria porque esos caracteres especiales están destinados a ser opcionales, no obligatorios [1].

  • Como dije antes, usted no especificó un filter real, así que gracias a la parte .{8,} , su expresión regular aceptará cualquier cadena siempre que cumpla con las condiciones establecidas por los lookaheads, incluso si tiene caracteres especiales no deseados [ 1].

Entonces para resolver esos defectos es necesario:

  • Eliminar la parte (?=.*?[#@$?]) .

  • Agregue un nuevo lookahead que actúe como el filter mencionado anteriormente.

Para build este filter, debe pensar "¿qué caracteres quiero permitir?" en lugar de "¿qué caracteres quiero desautorizar?", porque ese es un escenario más fácil de manejar en este caso específico. Si dices que solo quieres az , AZ , 0-9 y #@$? para ser sus personajes permitidos, entonces el futuro debe verse así:

 (?=[a-zA-Z0-9#@$?]) 

Pero, oye, en este paso incluso puedes establecer la longitud mínima e indicar el futuro por dónde empezar y dónde detenerse (el inicio y el final de la cadena en este caso):

 (?=[a-zA-Z0-9#@$?]{8,}$) 

Omití el ^ aquí porque ya está al principio de todo, por lo que no es necesario ser networkingundante. Ahora solo reunimos todos los lookaheads y hacemos coincidir la contraseña válida usando .* lugar de .{8,} :

 ^(?=[a-zA-Z0-9#@$?]{8,}$)(?=.*?[az])(?=.*?[AZ])(?=.*?[0-9]).* 

Nota:

  1. Aunque, en la expresión regular y los ejemplos que proporcionó, realmente no sé por qué: 1) #@$? no fueron tratados como obligatorios; 2) los caracteres no deseados solo se permitían al final de la cadena y no en otro lugar. Tal vez tiene algo que ver con el motor de expresiones regulares utilizado por AWS, porque todo funcionó como se esperaba cuando lo probé por mi count.

Queremos un anclaje anticipado en el inicio de la secuencia para cada tipo de carácter requerido, así como el requisito de longitud. Entonces un simple .* Para sorber todo:

 ^(?=[0-9a-zA-Z#@\$\?]{8,}$)(?=[^az]*[az])(?=[^AZ]*[AZ])(?=[^0-9]*[0-9]).* 

Explicación:

En primer lugar, decidí evitar el uso del cuantificador perezoso al hacer coincidir los types de caracteres requeridos (por ejemplo, una letra mayúscula) por las siguientes razones:

  • Son caros.
  • Diferentes motores de expresiones regulares tienen diferentes forms de significar perezoso. (Una pareja no lo admite en absoluto).
  • No son tan comunes / familiares como la alternativa.

Entonces, para eficiencia, legibilidad y "portabilidad" estoy usando la construcción ^[^x]*[x] .

Ahora rompiendo el rest …

^ : Todo anclado al comienzo

(?=[0-9a-zA-Z#@\$\?]{8,}$) : Busque con 8 o más de sus caracteres permitidos entre el inicio y el final de la cadena.

Los siguientes tres usan el mismo patrón: un vistazo que coincida con cero o más de un char que no coincida con un char requerido, luego el char requerido. Todos están anclados al principio, por lo que el efecto es permitir una coincidencia del carácter requerido en cualquier position de la cadena:

(?=[^az]*[az]) : Al less una minúscula.

(?=[^AZ]*[AZ]) : Al less una mayúscula.

(?=[^0-9]*[0-9]) : Al less un dígito.

.* : Todo lo anterior es un vistazo que no consume nada, así que consum todo aquí. El primer vistazo anticipa que la cadena completa tenga caracteres válidos, por lo que es seguro.

No pretendo que esto esté siendo optimizado (excepto para evitar el cuantificador perezoso). Esta es simplemente una de las forms más fáciles de comprender.


Nota: ¿la causa del problema que observó con #@$? se debe a que la búsqueda no está anclada al final de la cadena. Cualquier personaje coincidirá después de uno de esos cuatro (y no necesariamente solo en la última position). Por supuesto, no puede agregar $ ya que eso excluye a los personajes válidos. Es por eso que incluyo todos los caracteres válidos en el mismo lookahead.

Su expresión regular no prohíbe ningún personaje, solo requiere una instancia de cada class. Para restringir los caracteres permitidos, cambie su . (lo que significa cualquier carácter) al set de caracteres permitidos:

 ^(?=.*?[AZ])(?=.*?[az])(?=.*?[0-9])(?=.*?[#@$?])[a-zA-Z0-9#@$?]{8,}$ 

Tenga en count que si eso significa ser una cadena perl , necesitaría escaping de los $ s y @ s o usar comillas fuertes ( '...' o q{...} ). También quiere asegurarse de que la expresión regular funcione en modo ASCII ( az solo coincide con las letras en inglés, y coincide con cualquier byte).

Quite el (?=.*?[#@$?]) Si no necesita al less uno de esos símbolos.