15 expresiones regulares que te ahorrarán dolores de cabeza como Junior (y Senior)
Horas y horas intentando crear esa expresión regular predilecta para tus proyectos de extracción de datos y/o validación de datos en formularios, sin darte cuenta de que no conoces de verdad las expresiones regulares.
Por ende, muchos solemos odiarlas: No por lo que son, sino por lo poco intuitivas y difíciles de memorizar. Razón de ello, te compartiré al final del artículo algunas herramientas y servicios web que serán tus mejores amigos (como lo son para mi) en estos sui géneris sucesos. Y espero que os no te hallas perdido la función genérica para validar Tarjetas de Crédito y su tipo compartida en la publicación anterior ¿Eh?
—
EXPLICACIÓN BREVE DEL TÉRMINO
Si es tu primera vez sobre las expresiones regulares, solo imagínate un patrón que te ayuda a coincidir, ubicar y administrar un texto ya sea en tu código del programa, líneas de comando y hasta en editores de texto para buscar texto específico en un archivo.
Parece ser un idioma diferente, y si, es el idioma que todos los lenguajes de programación entienden en común y de allí su nombre: Regular (o lenguaje alien).
Aquellas coincidencias específicas en los que las funciones nativas del lenguaje, frameworks o SDKs no logran traer consigo, es esto tu As bajo la manga.
Dominar las expresiones regulares podrá ahorrarte miles de horas si trabajas con texto o necesitas analizar inmensa cantidad de datos (la gente de Perl sabe mejor esto que nosotros 😎: El lenguaje de solo escritura).
Comencemos con el Top 15 que según mi experiencia, querrás mantenerlas guardaditas para cuando llegue su momento por ser las más frecuentes en escala mundial.
1-) Nombre de usuario: Cualquier letra, un guión bajo o ninguno, y entre 3 a 16 caracteres.
"^(?=.*[a-z])(?=.*[a-z])(?=.*\d)[a-z\d\w\W]{8,}$"
Resultado:
Obtén el snippet acá: https://regexr.com/5q0fl
2-) Contraseña: Mínimo 8 caracteres, al menos 1 letra y 1 número
"^(?=.*[a-z])(?=.*\d)[a-z\d\w\W]{8,}$"
Resultado:
Obtén el snippet acá: https://regexr.com/5q05t
3-) Contraseña: Mínimo 8 caracteres, al menos 1 letra, 1 número y 1 carácter especial.
"^(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-_]).{8,}$"
Resultado:
Obtén el snippet acá: https://regexr.com/5q09u
4-) Contraseña: Mínimo 8 caracteres, al menos 1 letra mayúscula, 1 letra minúscula, 1 número y 1 carácter especial:
"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-_]).{8,16}$"
Resultado:
Obtén el snippet acá: https://regexr.com/5q0a9o
5-) Contraseña máxima seguridad: Incluso si quieres restringir el máximo anterior a 16 caracteres, pero con un mínimo de 8, sería así:
"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-_]).{8,16}$"
Resultado:
Obtén el snippet acá: https://regexr.com/5q0a7
6-) Correo electrónico: Versión rápida.
"^\S+@\S+\.\S+$"
NOTA: Si coincidiría pero con muchos símbolos extraños y errores tipográficos con el dominio.
Resultado:
Obtén el snippet acá: https://regexr.com/5q0ad
7-) Correo electrónico: Versión completa y con 99.9% de precisión validada por la especificación RFC 5322.
"(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])"
Resultado:
Obtén el snippet acá: https://regexr.com/5q0ap
PLUS: Si deseas echarle un vistazo al diagrama de ferrocarril sobre esta expresión regular, aquí te lo comparto:
8-) Código postal para 5 (90807) o 9 números (92064–3404):
"\d{5}-\d{4}|\d{5}"
Resultado:
Obtén el snippet acá: https://regexr.com/5q0bh
NOTA: No hay una única expresión regular que pueda controlar todos los códigos postales, esto es debido que los códigos postales de todo el mundo no se amarran a un patrón único. Si gustas, echa una miradilla a esta lista que contiene el RegEx expecífico por cada país. Créditos: @Chi.
9-) Formato de teléfono común: (111)-222–2222
"\(\d\d\d\) \d\d\d-?\d\d\d\d"
Resultado:
Obtén el snippet acá: https://regexr.com/5q0ci
10-) Fechas incluyendo el formato: dd-MM-YYYY, dd-mmm-YYYY, dd/mmm/YYYY ó dd.mmm.YYYY
"^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]|(?:Jan|Mar|May|Jul|Aug|Oct|Dec)))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2]|(?:En|Mar|Abr|May|Jun|Jul|Ago|Sep|Oct|Nov|Dic))\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)(?:0?2|(?:Feb))\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9]|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep))|(?:1[0-2]|(?:Oct|Nov|Dec)))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$"
Resultado:
Obtén el snippet acá: https://regexr.com/5q0d4
11-) Formato de tiempo: HH:MM 12 horas, con 0 inicial opcional y meridianos (am/pm)
"((1[0-2]|0?[1-9]):([0-5][0-9]) ?([AaPp][Mm]))"
Resultado:
Obtén el snippet acá: https://regexr.com/5q0dm
NOTA: Si requieres formato 24 con 0 -cero- inicial opcional (e.g.: HH:MM 24-horas), acá el patrón:
"^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$"
Por si acaso, los segundos son requeridos para usted en la coincidencia (e.g.: HH:MM:SS 24-horas), píllate esta (OjO: Requieres el 0 -cero- inicial):
"(?:[01]\d|2[0123]):(?:[012345]\d):(?:[012345]\d)"
12-) URL (Uniform Resource Locator) con protocolo Http(s)
"https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)"
Resultado:
Obtén el snippet acá: https://regexr.com/5q0e8
NOTA: En caso de no necesitar validar el protocolo http(s), quizás querrás solo usar esta versión del patrón:
[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)
13-) Dirección IPv4 o IPv6 (ambas en un mismo patrón):
"((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))"
Resultado:
Obtén el snippet acá: https://regexr.com/5q0et
14-) Ruta de archivo con nombre de archivo y extensión (incluye ruta de archivo vía Http(s))
"((\/|\\|\/\/|https?:\\\\|https?:\/\/)[a-z0-9 _@\-^!#$%&+={}.\/\\\[\]]+)+\.[a-z]+$"
Resultado:
Obtén el snippet acá: https://regexr.com/5q0f0
15-) Encontrar duplicados en una cadena:
"(\b\w+\b)(?=.*\b\1\b)"
Resultado:
Obtén el snippet acá: https://regexr.com/5q0h5
16-) Y LA ÑAPA! (el guineo verde): Validar alguna cédula de identidad y electoral (e.g.: República Dominicana 🏝️🇩🇴)
"[0-9]{3}-?[0-9]{7}-?[0-9]{1}$"
Resultado:
Obtén el snippet acá: https://regexr.com/5q0fc
—
Recuerda (y como comenta Geon George, autor de: iHateRegex): No es memorizarlas, es comprenderlas, motivo la cual este servicio web fue creado.
Esa web, además de actuar como repositorio, te arma gráficos por cada una de ellas explayando su funcionamiento. ¡Bastante chulo! ¿No? Entre otras cosas más como recopilar “chuletas” de expresiones regulares, expresiones más frecuentes y edición sobre la marcha del código que te proporciona. ¡Disfruta de su playground con ella para crear las tuyas desde 0!
También Regexpal es otra de las clásicas herramientas para probar expresiones reguladores. Por un lado tienes al objetivo, y por el otro, la expresión regular que aplica en JavaScript. ¡Incluye una versión para Android por si andáis por el camino en esta semana santa mientras lees este artículo!
Regex101 Otros de los competidores duros con un UI fácil de usar, grupos de captura de códigos de colores y también web platform. Me encanta la forma rápida en que copia la expresión, incluyendo los flags.
Y para concluir con una interesante aspirina, acá te dejo al Generador de Regex usando inglés plano: Regex Builder Tool ¡Si, escuchaste bien! Creas expresiones regulares usando el inglés simple para sus datos de muestras y coincidencias de prueba. Simplemente puedes usar frases en inglés sencillas de las sugerencias automáticas y la herramienta irá generando expresiones regulares para ello. ¿Maravilla, no?
Píllate un ejemplo de captura de declaración de registra de esta herramienta (e.g.: Etiquetas HTML)
_Match_anywhere_in_text_ _exact_string_ ( <) _then_ _once_or_not_at_all_of_ ( /) _then_ _one_or_more_of_ ( _any_word_character_) _then_ _zero_or_more_of_ ( _as_less_as_possible_of_ _any_character_) _then_ _exact_string_ ( >)
Este el patrón como resultado:
<\/?\w+.*?>
—
Lo odiemos o no, serán nuestros aliados las expresiones regulares para cualquier programador. Los web crawlers lo usan de Bocagrips al momento de “parsear” textos, otros para validar campos, y siempre que llega la hora de editar/refactorizar inmensas líneas de código en proyectos legados o analizar logs, tropezarse con esas cosas feas de Apache y sus redirecciones, también el RegEx cumple su mejor papel. 💪🏻
Espero que estas 15 + 1 expresiones regulares te ahorren un “Google > regex” eventualmente y si entiendes que es un buen intento de recopilación pero no suficiente, déjame saber en tus comentarios.