Las expresiones regulares son una de las herramientas más poderosas y más odiadas en programación — poderosas porque condensan una lógica compleja de coincidencia de cadenas en unos pocos caracteres, odiadas porque esos caracteres son famosamente ilegibles y propensos a errores. Dominar regex rinde frutos en todos los lenguajes y en casi todos los roles técnicos: búsqueda y reemplazo en editores, validación de formularios, análisis de registros, extracción de datos, reglas de enrutamiento y manipulación de texto en la línea de comandos con herramientas como grep y sed. Las secciones a continuación cubren la sintaxis central que todo desarrollador debería conocer, los patrones comunes que aparecen en el trabajo real y la disciplina de prueba que separa el regex que funciona del que da miedo.

La Sintaxis Central Que Todo Desarrollador Debe Conocer

La sintaxis de regex parece intimidante pero los elementos centrales son finitos y vale la pena memorizarlos. Las clases de caracteres son la base: `\d` coincide con cualquier dígito, `\w` coincide con cualquier carácter de palabra (letras, dígitos, guion bajo), `\s` coincide con cualquier espacio en blanco, y sus versiones en mayúscula (`\D`, `\W`, `\S`) coinciden con lo inverso. Los corchetes definen clases de caracteres personalizadas: `[abc]` coincide con cualquiera de esos tres caracteres, `[a-z]` coincide con cualquier letra minúscula, `[^0-9]` coincide con cualquier cosa excepto dígitos. Los cuantificadores especifican cuántas veces debe coincidir un patrón: `*` es cero o más, `+` es uno o más, `?` es cero o uno (opcional), `{3}` es exactamente 3, `{3,5}` es de 3 a 5, `{3,}` es 3 o más. Los cuantificadores son codiciosos por defecto, coincidiendo con todo lo posible; agregar `?` los hace perezosos (`*?`, `+?`). Las anclas coinciden con posiciones en lugar de caracteres: `^` es inicio de cadena (o de línea con la bandera `m`), `$` es fin de cadena, `\b` es un límite de palabra. La agrupación usa paréntesis `(...)` tanto para agrupar operadores como para capturar el texto coincidente para una referencia posterior. Estos bloques de construcción centrales cubren el 90% de las necesidades prácticas de regex, y la mayor parte del misterio del regex se disuelve una vez que internalizas este vocabulario. Todo lo demás son variaciones sobre estos temas.

Patrones Comunes Que Aparecen en el Trabajo Real

Un puñado de patrones surge tan a menudo entre proyectos que vale la pena memorizarlos como plantillas. Dirección de correo (validación laxa): `/^[\w.+-]+@[\w-]+\.[\w.-]+$/` — suficientemente bueno para filtrado de formularios, aunque el regex de correo formalmente correcto es imposiblemente largo para escribirlo a mano. Coincidencia de URL: `/https?:\/\/[^\s]+/g` — bien para extraer URLs de texto, aunque captura signos de puntuación finales que querrás recortar. Números de teléfono de EE. UU.: `/\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{4}/` — maneja paréntesis, guiones y espacios como separadores opcionales. Direcciones IP (IPv4): `/\b(?:\d{1,3}\.){3}\d{1,3}\b/` — simple pero no rechaza 999.999.999.999 (eso requiere una fea lógica de restricción de valor). Fechas ISO: `/\d{4}-\d{2}-\d{2}/` con grupos con nombre opcionales `(?\d{4})-(?\d{2})-(?\d{2})` para extracción. Colores hexadecimales: `/#[0-9a-f]{3,8}\b/i`. Número de tarjeta de crédito (laxo): `/\b\d{13,19}\b/` — solo para verificación de formato, no de validez. UUID: `/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i`. La biblioteca de patrones en la mayoría de los sitios de regex amplía sustancialmente este conjunto, y copiar un patrón probado en batalla casi siempre es mejor que escribir el tuyo para formatos comunes. Nombra tus grupos de captura cuando necesites extraer datos — la sintaxis `(?...)` hace el código resultante dramáticamente más legible que `match[1]` / `match[2]`.

Disciplina de Prueba: Cómo Escribir Regex Que Realmente Funcione

La diferencia entre el regex que funciona de forma confiable y el que rompe producción es la disciplina de prueba. Cuatro prácticas distinguen consistentemente ambos. Primero, prueba siempre con casos positivos (entradas que deberían coincidir) Y casos negativos (entradas que no deberían coincidir). Es fácil crear un patrón que coincida con todo lo que quieres, solo para descubrir que también coincide con entradas que no querías. Un conjunto de prueba con 10 positivos y 10 negativos detecta la mayoría de los problemas. Segundo, prueba específicamente contra casos límite: cadena vacía, un solo carácter, cadenas muy largas, caracteres Unicode, cadenas con solo espacios en blanco, cadenas con saltos de línea, cadenas con caracteres especiales de regex. Los patrones de regex tienen un comportamiento sorprendente en torno a estos límites, y las entradas de producción eventualmente incluirán todos ellos. Tercero, cuídate del retroceso catastrófico. Un patrón como `(a+)+b` probado contra `aaaaaaaaaaaaaaaaX` puede tomar tiempo exponencial porque el motor prueba cada posible agrupación de las `a`. Prueba cualquier patrón complejo contra entradas de aspecto malicioso (cadenas largas de caracteres repetidos) y observa el tiempo de ejecución. Los ataques ReDoS (Denegación de Servicio por Expresión Regular) explotan exactamente esta vulnerabilidad en patrones mal diseñados usados en la validación de entradas. Cuarto, usa un probador de regex real (este, o un complemento de editor) durante el desarrollo en lugar de prueba y error en el código de producción — la retroalimentación visual de ver las coincidencias resaltarse en vivo mientras escribes produce patrones funcionales de 5 a 10 veces más rápido que depurar pruebas fallidas después del hecho.