2009-08-03 43 views
29

Esto parece coincidir con las reglas que he definido, pero esta noche solo empiezo a aprender a usar expresiones regulares, así que me pregunto si es correcto.¿Cómo validar un nombre de usuario con expresiones regulares?

Reglas:

  • Los nombres de usuario puede consistir en minúsculas y capitales
  • Los nombres de usuario pueden consistir en alfanumérica personajes
  • nombres de usuario pueden consistir subrayado y guiones y espacios
  • no puede haber dos guiones , dos hypens o dos espacios en una fila
  • Can no tienen un guión bajo, hypen o espacio al principio o al final

patrón de expresión:

/^[a-zA-Z0-9]+([a-zA-Z0-9](_|-|)[a-zA-Z0-9])*[a-zA-Z0-9]+$/ 
+4

Esto no permitirá caracteres no latinos en los nombres de usuario. Si desea poder manejar caracteres no latinos, debe usar una clase de caracteres incorporada en lugar de definir explícitamente qué caracteres son letras y números. – Welbog

+2

Puede probar su expresión en línea: http://www.gskinner.com/RegExr/ – twk

+0

'/^[a-zA-Z0-9] + ([a-zA-Z0-9] (_ | - |) [a-zA-Z0-9]) * [a-zA-Z0-9] * $/'es suficiente. No es necesario agregar '+' en el último –

Respuesta

53

Las especificaciones en la pregunta no son muy claras, así que supongo que la cadena puede contener solo letras y dígitos ASCII, con guiones, guiones bajos y espacios como separadores internos. La esencia del problema es asegurar que el primer y el último personaje no sean separadores, y que nunca haya más de un separador en una fila (esa parte parece clara, de todos modos). Esta es la forma más sencilla:

/^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/ 

Después de comparar uno o más caracteres alfanuméricos, si hay un separador, se debe ser seguido por uno o más caracteres alfanuméricos; repita según sea necesario.

Echemos un vistazo a las expresiones regulares de algunas de las otras respuestas.

/^[[:alnum:]]+(?:[-_ ]?[[:alnum:]]+)*$/ 

Esto es efectivamente lo mismo (asumiendo que su sabor es compatible con la notación de expresiones regulares de clase de caracteres POSIX), pero ¿por qué hacer el separador opcional? La única razón por la que estarías en esa parte de la expresión regular en primer lugar es si hay un separador u otro personaje no válido.

/^[a-zA-Z0-9]+([_\s\-]?[a-zA-Z0-9])*$/ 

Por otro lado, esto sólo funciona porque el separador es opcional. Después del primer separador, solo puede coincidir con un alfanumérico a la vez. Para que coincida más, tiene que seguir repitiendo todo el grupo: separadores de cero seguidos de un alfanumérico, una y otra vez. Si el segundo [a-zA-Z0-9] fuera seguido por un signo más, podría encontrar una coincidencia por una ruta mucho más directa.

/^[a-zA-Z0-9][a-zA-Z0-9_\s\-]*[a-zA-Z0-9](?<![_\s\-]{2,}.*)$/ 

Este utiliza de búsqueda hacia atrás sin límites, que es una característica muy rara, pero se puede utilizar una búsqueda hacia delante en el mismo sentido:

/^(?!.*[_\s-]{2,})[a-zA-Z0-9][a-zA-Z0-9_\s\-]*[a-zA-Z0-9]$/ 

Esto realiza esencialmente una búsqueda separada por dos separadores consecutivos, y falla el partido si encuentra uno. El cuerpo principal solo necesita asegurarse de que todos los caracteres sean alfanuméricos o separadores, y que el primero y el último sean alfanuméricos. Dado que esos dos son obligatorios, el nombre debe tener al menos dos caracteres de longitud.

/^[a-zA-Z0-9]+([a-zA-Z0-9](_|-|)[a-zA-Z0-9])*[a-zA-Z0-9]+$/ 

Ésta es su propia expresión regular, y requiere la cuerda para empezar y terminar con dos caracteres alfanuméricos, y si hay dos separadores dentro de la cadena, no tiene por qué ser exactamente dos caracteres alfanuméricos entre ellos. Así que ab, ab-cd y ab-cd-ef coincidirán, pero a, a-b y a-b-c no lo harán.

Además, como han señalado algunos de los comentaristas, el (_|-|) en su expresión regular debería ser [-_ ]. Esa parte no es incorrecta, pero si puede elegir entre una alternancia y una clase de caracteres, siempre debe ir con la clase de caracteres: son más eficientes y más legibles.

De nuevo, no me preocupa si se supone que "alfanumérico" debe incluir caracteres no ASCII, o el significado exacto de "espacio", cómo aplicar una política de separadores internos no contiguos con una expresión regular.

+0

bien, y cómo limitar esto? algo así como: ^ ([a-zA-Z0-9] + ([a-zA-Z0-9] (_ | - |) [a-zA-Z0-9]) * [a-zA-Z0- 9] +) {6,25} $ –

+0

@GabrielAnderson: ¿Quiere decir que el nombre completo (incluidos los separadores) debe tener al menos 6 y como máximo 25 caracteres de largo? Eso requiere un vistazo. Simplemente agregue '(? =. {6,25} $)' al comienzo, justo después del anclaje ('^'). –

3

Sugiero escribir algunas pruebas unitarias para poner la expresión regular a su propio ritmo. Esto también ayudará en unos meses a partir de ahora cuando encuentre un problema con Regex y necesite actualizarlo.

+2

+1. Definitivamente es una buena idea cubrir las expresiones regulares con varias pruebas unitarias –

4
([a-zA-Z0-9](_|-|)[a-zA-Z0-9])* 

es un 0 o más repetiton de alphanum, dashspace, alphanum.

Por lo que se correspondería con

a_aa_aa_a 

pero no

aaaaa 

La expresión regular completa no puede igualar

a_aaaaaaaaa_a for example. 

Vamos a mirar hacia atrás en lo que quiere:

* Usernames can consist of lowercase and capitals or alphanumerica characters 
* Usernames can consist of alphanumeric characters 
* Usernames can consist of underscore and hyphens and spaces 
* Cannot be two underscores, two hypens or two spaces in a row 
* Cannot have a underscore, hypen or space at the start or end 

El comienzo es simple ... simplemente haga coincidir un alphanum, luego (anotando los dos en la regla de la fila) an (alphanum o dashspace) * y al y un alfanum nuevamente.

Para evitar los dos espacios del tablero en una fila, es probable que necesite entender lookahead/lookbehind.

Ah, y con respecto a la otra respuesta: descargue Espresso, REALMENTE le ayuda a entender esas cosas.

+2

darle a un hombre un pescado, o enseñar a un hombre a pescar ...? Es un dilema –

+1

Fácil: dale a un hombre un pez * mientras * le enseñas a pescar. :) –

+1

¿Le muestra a un hombre cómo pescar al pescar un pez usted mismo para demostrar que sus métodos funcionan? – Kzqai

2
  1. alfanumérico no es sólo [a-zA-Z0-9], ha acentuado, cirílico, griego y otras letras, que pueden ser utilizados en nombre de usuario.

  2. (_|-|) puede ser reemplazado por clase [-_ ] carácter

+4

'[_-]' es "todo entre subrayado y espacio". Desea tener el guión primero para que se interprete correctamente: '[-_]' – Welbog

0

Otra recomendación para Expresso 3.0 aquí - muy fácil de usar y construir cadenas con.

0

Su expresión regular no funciona. La parte difícil es la verificación de espacios/guiones consecutivos.Se podría utilizar éste, que utiliza mirar detrás:

/^[a-zA-Z0-9][a-zA-Z0-9_\s\-]*[a-zA-Z0-9](?<![_\s\-]{2,}.*)$/ 
+0

Esto no funcionará en la mayoría de los motores de expresiones regulares porque la secuencia de búsqueda detrás no es de longitud fija. – mikej

+0

El motor de expresiones regulares de .NET me ha echado a perder :) –

+0

Sí, quise mencionar en mi comentario que el motor .NET es uno de los pocos en los que * * funcionará :-) – mikej

0

Por lo visto, esa norma no se correspondería con algo así como "a_bc", "ab_c", "A_B" o "a_b_c".

Probar: /^[a-zA-Z0-9]+([_\s\-]?[a-zA-Z0-9])*$/ que coincida con los casos anteriores, pero no con cualquier combinación de espacios, guiones o guiones bajos uno al lado del otro. Por ejemplo: "_-" o "_" no están permitidos.

1

Uso de la clase de caracteres POSIX para caracteres alfanuméricos para hacer que funcione para los caracteres acentuados y otros extranjeros alfabéticos:

/^[[:alnum:]]+([-_ ]?[[:alnum:]])*$/ 

más eficientes (evita capturas):

/^[[:alnum:]]+(?:[-_ ]?[[:alnum:]]+)*$/ 

Estos también evitan que las secuencias de más de un espacio/guión/guión bajo en combinación. No se desprende de su especificación si eso es deseable, pero su propia expresión regular parece indicar que esto es lo que quiere.

12

Usted expresión regular puede simplificarse a:

/^[a-zA-Z0-9]+([_ -]?[a-zA-Z0-9])*$/ 

visualizado con Regexper:

Visualization of username validation regex.

Como se puede ver un nombre de usuario siempre tiene que empezar con un carácter alfanumérico. Los caracteres especiales (_, , -) deben ir seguidos de un carácter alfanumérico. El último personaje tiene que ser un personaje alfanumérico.

Cuestiones relacionadas