2011-07-18 20 views
6

Iba a escribir una expresión regular que coincidiría solo si una cadena contiene al menos n clases diferentes de caracteres. Yo iba a usar esto para forzar a mis usuarios para crear contraseñas seguras y quería comprobar si la contraseña contiene al menos 3 de los siguientes:Igualación de expresiones regulares al menos n de m grupos

  • Caracteres
  • capitales Caracteres
  • Números
  • Caracteres especiales

Escribir una expresión regular que coincida si todas esas clases están presentes es trivial usando lookaheads. Sin embargo, no puedo envolver mi cabeza con la parte "al menos 3". ¿Es esto posible (en una expresión agradable y compacta) o tendré que crear una expresión de monstruo?

Respuesta

6

creo que esto será más compacto que la lista cada posible combinación de 3 de los 4. Utiliza búsqueda negativa hacia delante para asegurarse de que toda la cadena no está compuesto de sólo una o dos de las clases de personajes que enumeró:

(?!([a-zA-Z]*|[a-z\d]*|[^A-Z\d]*|[A-Z\d]*|[^a-z\d]*|[^a-zA-Z]*)$).* 

En orden, los grupos aquí son:

  • inferior y superior/inferior
  • y/o dígitos o
  • inferior y/o r especiales
  • superior y/o dígitos
  • superior y/o especiales
  • dígitos y/o especial

Esta expresión regular fallará si la cadena completa (debido a la $ en la búsqueda negativa hacia delante) contiene solo caracteres de cualquiera de los grupos anteriores.

+1

Me gusta mucho este enfoque. Ni siquiera pensé en invertir la lógica. Muchas gracias, muy inteligente! –

+1

¿No es esta expresión que permite espacios? – Rookian

+1

Lo hace, [no es raro que las contraseñas permitan espacios] (http://stackoverflow.com/questions/632167/should-users-be-allowed-to- ingresred-a-password-with-a-space- at-the-beginning-or-e). Si necesita una versión que no permite espacios, cambie el '. *' Al final a '\ S *'. –

2

Tiene que escribir una expresión para cada combinación posible de 3 de los 4 (cuatro expresiones en total), y luego | las expresiones individuales juntas para que pasen si cumplen al menos una de las expresiones originales.

+1

Que es 4 expresiones cada una aproximadamente 3/4 de la longitud de su expresión regular actual, por lo que su resultado final sería de aproximadamente 3 veces el tamaño de su expresión regular actual. No está mal. – Paulpro

+0

Esperaba que no tuviera que hacer eso. Creo que no está limpio, especialmente porque tendré que volver a escribir las mismas clases una y otra vez. Gracias por su aclaración. –

+0

¿Por qué no está limpio? cree un método que lo haga y reutilícelo. Es mucho mejor que tener un único RegEx ilegible. –

0

¿Qué opina de esta solución?

var str='23khkS_s'; 

var countGroups=0; 
if(str.match(/[a-z]+/)) 
    countGroups++; 
if(str.match(/[A-Z]+/)) 
    countGroups++; 
if(str.match(/[0-9]+/)) 
    countGroups++; 
if(str.match(/[[email protected]#$%*\(\)]+/)) 
    countGroups++; 

console.log(countGroups); 

En lugar de usar 1 expresión similar a un monstruo, puede usar 4 pequeñas RE. Y luego trabaje con la variable countGroups, que contiene el número de grupos de caracteres atribuidos. Espero que sea útil

+0

Esto sería bueno si él controlara la solución completa de principio a fin, pero sospecho que todo lo que puede hacer es poner una expresión regular en un campo de texto para la configuración. –

Cuestiones relacionadas