2011-05-23 156 views
5

Estoy intentando escribir una validación de nombre de usuario que tiene las siguientes restricciones:expresión regular para validar los nombres de usuario con al menos una letra y sin caracteres especiales

  1. debe contener al menos 1 letra (a-ZA- Z)
  2. puede no contener nada más que cifras, letras o caracteres de subrayado

Los siguientes ejemplos son válidos: abc123, mi_nombre, 12345A

Los siguientes ejemplos no son válidos: 123456, mi_nombre !, _1235

Encontré algo sobre el uso de lookaheads positivos para el uso de la carta: (? =. * [a-zA-Z]), y parece que podría haber algún tipo de error Mirar hacia adelante para la segunda restricción, pero no estoy seguro de cómo mezclarlos en una expresión regular. (Nota ... No tengo muy claro qué hace la porción. * Dentro de la búsqueda anticipada ...)

¿Es algo como esto:/(? =. * [A-zA-Z]) (? !. * [^ a-zA-Z0-9 _])/

Editar:

Debido a que la pregunta se refiere a una expresión regular, la respuesta es que estoy aceptando:

/^[a-zA-Z0-9_]*[a-zA-Z][a-zA-Z0-9_]*$/ 

Sin embargo, lo que realmente voy a implementar es la sugerencia de Bryan Oakley de dividirlo en múltiples cheques más pequeños. Esto facilita la lectura y la ampliación en el futuro en caso de que cambien los requisitos. ¡Gracias a todos!

Y porque tagged esto con ruby-on-rails, voy a incluir el código realidad estoy usando:

validate :username_format  

def username_format 
    has_one_letter = username =~ /[a-zA-Z]/ 
    all_valid_characters = username =~ /^[a-zA-Z0-9_]+$/ 
    errors.add(:username, "must have at least one letter and contain only letters, digits, or underscores") unless (has_one_letter and all_valid_characters) 
end 

Respuesta

6

/^[a-zA-Z0-9_]*[a-zA-Z][a-zA-Z0-9_]*$/: 0 o más caracteres válidos seguidos de un orden alfabético seguido de 0 o más caracteres válidos, restringidos para ser tanto el principio como el final de la línea.

+0

Sweet, falta un _ en la primera prueba para 0 o más válidos, pero aparte de eso, ¡funciona! – Paul

2

la expresión regular simple que resuelve su problema es:

/^[a-zA-Z0-9][a-zA-Z0-9_]*$/ 

Lo animo a que lo pruebe en vivo en http://rubular.com/

+0

No es una solución perfecta: no permitirá 12345a. –

+0

Parece que esto está muy cerca, pero también impuso la restricción de que debe comenzar con una letra, por lo que 12345a no pasa. – Paul

+0

Lo siento, pensé que 12345a no es válido: el correcto es/^ [a-zA-Z0-9] [a-zA-Z0-9 _] * $/ –

6

Es fácil comprobar si el patrón tiene caracteres ilegales, y es fácil comprobar si hay al menos un le tter. Tratar de hacer eso todo en una expresión regular hará que su código sea difícil de entender.

Mi recomendación es hacer dos pruebas. Poner las pruebas de funciones para hacer su código-muertos absolutamente simple de entender:

if no_illegal_characters(string) && contains_one_alpha(string) { 
    ... 
} 

En el primer caso se puede utilizar el patrón ^[a-zA-Z0-9_]+$, y para este último puede utilizar [a-zA-Z].

Si no te gustan las funciones extra que están bien, simplemente no intentes resolver el problema con una expresión regular difícil de leer. No se otorgan puntos de bonificación por incluir tanta funcionalidad en una expresión como sea posible.

+0

Tienes razón, no hay necesidad de complicar demasiado esto. – Paul

+0

Hay un pequeño error en su expresión regular "no_illegal_characters()", Bryan. Como está ahora, la expresión regular dice "la cadena debe tener solo 1 carácter de principio a fin". En lugar de '^ [a-zA-Z0-9 _] $' debería ser '^ [a-zA-Z0-9 _] + $'. –

+0

Gracias @wyatt, he cambiado la expresión para incluir el '+' –

Cuestiones relacionadas