Estoy tratando de implementar una validación de formulario de nombre de usuario en javascript donde el nombre de usuario
ejemplo de un nombre de usuario válido: the_user-one.123
ejemplo de nombre de usuario inválido: 1----- usuario
He estado tratando de implementar esto por un tiempo, pero no pude encontrar la manera de tener solo uno de cada símbolo permitido : -
const usernameValidation = /(?=^[\w.-]+$)^\D/g console.log(usernameValidation.test('1username')) //false console.log(usernameValidation.test('username-One')) //truePrefacio: debido a mi grave descuido, supuse que el contexto era el uso del atributo de pattern HTML en lugar de la validación de entrada de JavaScript. Dejo esta respuesta aquí para la posteridad en caso de que alguien realmente quiera hacer esto con expresiones regulares.
Aunque regex tiene funcionalidad para representar un patrón que ocurre consecutivamente dentro de una cierta cantidad de veces (a través de {<lower-bound>,<upper-bound>} ), no tengo conocimiento de que regex tenga una funcionalidad "elegante" para hacer cumplir un conjunto de patrones, cada uno de los cuales ocurre dentro de un rango de número de veces pero en cualquier orden y con otros patrones posiblemente en el medio.
Algunas soluciones que se me ocurren:
Cree una expresión regular que permita una de cada permutación de ordenación de caracteres especiales (nota: se agregaron nuevas líneas para mejorar la legibilidad):
^(?: (?:(?:(?:[A-Za-z][A-Za-z0-9]*\.?)|\.)[A-Za-z0-9]*-?[A-Za-z0-9]*_?)| (?:(?:(?:[A-Za-z][A-Za-z0-9]*\.?)|\.)[A-Za-z0-9]*_?[A-Za-z0-9]*-?)| (?:(?:(?:[A-Za-z][A-Za-z0-9]*-?)|-)[A-Za-z0-9]*\.?[A-Za-z0-9]*_?)| (?:(?:(?:[A-Za-z][A-Za-z0-9]*-?)|-)[A-Za-z0-9]*_?[A-Za-z0-9]*\.?)| (?:(?:(?:[A-Za-z][A-Za-z0-9]*_?)|_)[A-Za-z0-9]*\.?[A-Za-z0-9]*-?)| (?:(?:(?:[A-Za-z][A-Za-z0-9]*_?)|_)[A-Za-z0-9]*-?[A-Za-z0-9]*\.?) )[A-Za-z0-9]*$Tenga en cuenta que la expresión regular anterior se puede simplificar si tampoco desea que los nombres de usuario comiencen con caracteres especiales.
Recordatorio amistoso para asegurarse de usar los atributos HTML para aplicar una longitud mínima y máxima de caracteres de entrada cuando corresponda.
Si cree que la expresión regular no se adapta bien a su caso de uso, sepa que puede hacer una lógica de validación personalizada usando javascript , lo que le brinda mucho más control y puede ser mucho más legible en comparación con la expresión regular, pero puede requerir más líneas de código para implementar. Al ver la expresión regular anterior, personalmente consideraría seriamente la ruta javascript personalizada.
Nota: Encuentro https://regex101.com/ muy útil para aprender, escribir y probar expresiones regulares. Asegúrese de establecer el "sabor" en "JavaScript" en su caso.
Debo admitir que la solución de Bobble Bubble es la mejor opción. He aquí una comparación de los diferentes casos:
console.log("Comparison between mine and Bobble Bubble's solution:\n\nusername mine,BobbleBubble"); ["valid-usrId1","1nvalidUsrId","An0therVal1d-One","inva-lid.userId","anot-her.one","test.-case"].forEach(u=>console.log(u.padEnd(20," "),chck(u))); function chck(s){ return [!!s.match(/^[a-zA-Z][a-zA-Z0-9._-]*$/) && ( s.match(/[._-]/g) || []).length<2, // mine !!s.match(/^(?!\d|.*?([_.-]).*\1)[\w.-]+$/)].join(","); // Bobble bulle }Las diferencias se pueden ver en los últimos tres casos de prueba.
¿Qué tal si usamos una anticipación negativa al principio?
^(?!\d|.*?([_.-]).*\1)[\w.-]+$Esto comprobará si la cadena
[_.-] por uso de captura y referencia inversaVea esta demostración en regex101 (más explicaciones en el lado derecho)