Expresiones Regulares: Una Guía Práctica con Ejemplos
· 12 min de lectura
Las expresiones regulares (regex) son una de las herramientas más poderosas en el kit de un desarrollador, sin embargo, a menudo son malinterpretadas o evitadas por completo. Ya sea que estés validando entrada de usuario, analizando archivos de registro o transformando datos de texto, regex proporciona una forma concisa y eficiente de hacer coincidir patrones en cadenas.
Esta guía completa te llevará desde los conceptos básicos de regex hasta técnicas avanzadas, con ejemplos prácticos que puedes usar inmediatamente en tus proyectos. Al final, entenderás no solo cómo funciona regex, sino cuándo y por qué usarlo.
Tabla de Contenidos
- ¿Qué es Regex y Por Qué Debería Importarte?
- Conceptos Básicos de Regex: Bloques de Construcción
- Cuantificadores: Controlando la Repetición
- Clases de Caracteres y Atajos
- Grupos y Capturas
- Anclas y Límites
- Patrones Comunes para Uso en el Mundo Real
- Banderas: Modificando el Comportamiento de Regex
- Técnicas Avanzadas
- Consejos de Rendimiento y Mejores Prácticas
- Prueba y Depuración de Regex
- Preguntas Frecuentes
¿Qué es Regex y Por Qué Debería Importarte?
Una expresión regular es una secuencia de caracteres que define un patrón de búsqueda. Piensa en ella como un mini-lenguaje diseñado específicamente para hacer coincidir patrones en texto. En lugar de buscar cadenas exactas, regex te permite describir patrones como "cualquier dirección de correo electrónico" o "todos los números de teléfono en este formato".
Regex es compatible con prácticamente todos los lenguajes de programación y muchas herramientas de línea de comandos. Una vez que aprendes la sintaxis, puedes aplicarla en todas partes—desde JavaScript y Python hasta grep y sed.
Los casos de uso comunes incluyen:
- Validar entrada de usuario (correos electrónicos, números de teléfono, contraseñas)
- Extraer datos de texto (analizar registros, extraer contenido)
- Operaciones de buscar y reemplazar (refactorizar código, limpiar datos)
- Enrutamiento de URL y coincidencia de patrones
- Resaltado de sintaxis y análisis léxico
Consejo profesional: Aunque regex es poderoso, no siempre es la herramienta correcta. Para tareas de análisis complejas como HTML o JSON, usa analizadores dedicados en su lugar. Regex funciona mejor para patrones bien definidos y relativamente simples.
Conceptos Básicos de Regex: Bloques de Construcción
Cada patrón regex se construye a partir de bloques de construcción fundamentales. Entender estos elementos centrales es esencial antes de pasar a patrones más complejos.
Caracteres Literales
El regex más simple es solo texto literal. El patrón cat coincide con la cadena exacta "cat" en tu texto. La mayoría de los caracteres alfanuméricos coinciden directamente consigo mismos.
Metacaracteres
Ciertos caracteres tienen significados especiales en regex. Estos se llaman metacaracteres e incluyen: . ^ $ * + ? { } [ ] \ | ( )
Para hacer coincidir estos caracteres literalmente, necesitas escaparlos con una barra invertida. Por ejemplo, \. coincide con un punto literal.
El Comodín de Punto
El punto . es el comodín más básico—coincide con cualquier carácter individual excepto nueva línea. El patrón a.c coincide con "abc", "a1c", "a-c", pero no con "ac" (sin carácter entre) o "a\nc" (nueva línea).
| Patrón | Coincide | Ejemplo |
|---|---|---|
. |
Cualquier carácter (excepto nueva línea) | a.c coincide con abc, a1c, a-c |
\d |
Cualquier dígito [0-9] | \d{3} coincide con 123, 456 |
\w |
Carácter de palabra [a-zA-Z0-9_] | \w+ coincide con hello, user_1 |
\s |
Espacio en blanco (espacio, tabulación, nueva línea) | \s+ coincide con espacios, tabulaciones |
\D |
No dígito | \D+ coincide con abc, xyz |
\W |
Carácter que no es de palabra | \W+ coincide con !@#, espacios |
\S |
No espacio en blanco | \S+ coincide con cualquier texto visible |
Observa que las versiones en mayúscula (\D, \W, \S) son el inverso de sus contrapartes en minúscula. Este es un patrón común en la sintaxis de regex.
Cuantificadores: Controlando la Repetición
Los cuantificadores especifican cuántas veces debe repetirse un patrón. Se colocan después del elemento que deseas repetir y son fundamentales para crear patrones flexibles.
Cuantificadores Básicos
| Cuantificador | Significado | Ejemplo |
|---|---|---|
* |
0 o más veces | ab*c coincide con ac, abc, abbc, abbbc |
+ |
1 o más veces | ab+c coincide con abc, abbc (no ac) |
? |
0 o 1 vez (opcional) | colou?r coincide con color, colour |
{n} |
Exactamente n veces | \d{4} coincide con 2026, 1999 |
{n,} |
n o más veces | \d{3,} coincide con 123, 1234, 12345 |
{n,m} |
Entre n y m veces | \d{2,4} coincide con 12, 123, 1234 |
Coincidencia Codiciosa vs. Perezosa
Por defecto, los cuantificadores son codiciosos—coinciden con tanto texto como sea posible. Esto puede llevar a resultados inesperados al hacer coincidir patrones como etiquetas HTML.
// Coincidencia codiciosa
const text = "<div>Hello</div><div>World</div>";
const greedy = /<.*>/;
// Coincide: "<div>Hello</div><div>World</div>" (¡cadena completa!)
// Coincidencia perezosa
const lazy = /<.*?>/;
// Coincide: "<div>" (se detiene en el primer corchete de cierre)
Agregar ? después de un cuantificador lo hace perezoso (no codicioso). Los cuantificadores perezosos coinciden con tan poco texto como sea posible mientras aún satisfacen el patrón.
Consejo rápido: Al hacer coincidir contenido entre delimitadores (comillas, corchetes, etiquetas), los cuantificadores perezosos son generalmente lo que quieres. Usa .*? en lugar de .* para evitar coincidir demasiado.
Clases de Caracteres y Atajos
Las clases de caracteres te permiten hacer coincidir cualquier carácter de un conjunto específico. Se definen usando corchetes y son increíblemente útiles para crear patrones flexibles.
Clases de Caracteres Básicas
// Coincidir cualquier vocal
/[aeiou]/
// Coincidir cualquier dígito
/[0-9]/
// Coincidir cualquier letra minúscula
/[a-z]/
// Coincidir cualquier letra (sin distinción de mayúsculas)
/[a-zA-Z]/
// Coincidir caracteres alfanuméricos
/[a-zA-Z0-9]/
Clases de Caracteres Negadas
Usa ^ al inicio de una clase de caracteres para negarla—coincidiendo con cualquier carácter excepto los listados.
// Coincidir cualquier no dígito
/[^0-9]/
// Coincidir cualquier no vocal
/[^aeiou]/
// Coincidir cualquier carácter excepto espacio o tabulación
/[^ \t]/
Caracteres Especiales en Clases
La mayoría de los metacaracteres pierden su significado especial dentro de las clases de caracteres. Puedes incluir ., *, + y ? sin escaparlos. Sin embargo, aún necesitas escapar ], \, ^ y - en ciertas posiciones.
// Coincidir un punto o coma
/[.,]/
// Coincidir un guion (escapar o colocar al inicio/final)
/[-a-z]/ o /[a-z-]/
// Coincidir un corchete de cierre (debe escaparse)
/[\]]/
Grupos y Capturas
Los grupos sirven para dos propósitos principales: te permiten aplicar cuantificadores a múltiples caracteres, y capturan texto coincidente para uso posterior.
Grupos de Captura
Los paréntesis crean grupos de captura que recuerdan el texto coincidente. Esto es esencial para extraer datos de cadenas.
// Extraer componentes de fecha
const datePattern = /(\d{4})-(\d{2})-(\d{2})/;
const match = "2026-03-29".match(datePattern);
// match[0]: "2026-03-29" (coincidencia completa)
// match[1]: "2026" (primer grupo)
// match[2]: "03" (segundo grupo)
// match[3]: "29" (tercer grupo)
Grupos de Captura Nombrados
Los grupos nombrados hacen tu regex más legible y tu código más mantenible. En lugar de referirte a grupos por número, les das nombres descriptivos.
// Sintaxis de grupos nombrados: (?<name>pattern)
const datePattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = "2026-03-29".match(datePattern);
// Acceder por nombre
console.log(match.groups.year); // "2026"
console.log(match.groups.month); // "03"
console.log(match.groups.day); // "29"
Grupos sin Captura
A veces necesitas agrupar para cuantificadores o alternancia pero no quieres capturar el texto. Los grupos sin captura usan la sintaxis (?:...).
// Capturar el protocolo sin crear un grupo
/(?:https?|ftp):\/\/([a-z.]+)/
// Esto crea solo un grupo de captura (el dominio)
// El grupo de protocolo (?:https?|ftp) no captura
Los grupos sin captura son más rápidos y usan menos memoria que los grupos de captura. Úsalos cuando no necesites el texto capturado.
Referencias Inversas
Las referencias inversas te permiten hacer coincidir el mismo texto que fue capturado por un grupo anterior. Esto es útil para encontrar palabras repetidas o hacer coincidir delimitadores emparejados.
// Encontrar palabras repetidas
/\b(\w+)\s+\1\b/
// Coincide con "the the" o "hello hello"
// Coincidir comillas emparejadas
/(['"])(.*?)\1/
// Coincide con "hello" o 'world' pero no "mixed'
Alternancia
El operador de barra vertical | crea alternancia—coincidiendo con un patrón u otro. Es como un OR lógico.
// Coincidir cat, dog o bird
/cat|dog|bird/
// Coincidir extensiones de archivo comunes
/\.(jpg|jpeg|png|gif|webp)$/i
// Coincidir Mr., Mrs., Ms. o Dr.
/(?:Mr|Mrs|Ms|Dr)\./
Anclas y Límites
Las anclas no coinciden con caracteres—coinciden con posiciones en la cadena. Son esenciales para asegurar que los patrones aparezcan en ubicaciones específicas.
Anclas de Cadena
^coincide con el inicio de la cadena (o línea en modo multilínea)$coincide con el final de la cadena (o línea en modo multilínea)
// Debe comenzar con "Hello"
/^Hello/
// Debe terminar con "world"
/world$/
// La cadena completa debe ser exactamente 5 dígitos
/^\d{5}$/
Límites de Palabra
El ancla \b coincide con límites de palabra—posiciones entre caracteres de palabra y no palabra. Esto es crucial para hacer coincidir palabras completas.
// Coincidir "cat" como palabra completa
/\bcat\b/
// Coincide: "cat", "the cat sat"
// No coincide: "category", "scat"
// Coincidir palabras que comienzan con "pre"
/\bpre\w+/
// Coincide: "preview", "prepare", "prefix"
El inverso \B coincide con no límites de palabra—posiciones donde ambos lados son caracteres de palabra o ambos son caracteres que no son de palabra.
Consejo profesional: Siempre usa límites de palabra al buscar palabras completas. Sin ellos, buscar "cat" también coincidirá con "category" y "concatenate". El patrón \bcat\b asegura que solo coincidas con la palabra completa.
Patrones Comunes para Uso en el Mundo Real
Aquí hay patrones regex probados en batalla para tareas comunes de validación y extracción. Estos patrones equilibran simplicidad con precisión práctica.
| Tipo de Patrón | Regex | Notas |
|---|---|---|
| Email (simple) | ^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,}$ |
Bueno para validación básica |
| Email (compatible con RFC) | ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ |
Más estricto, ampliamente aceptado |
| URL | ^https?:\/\/[\w.-]+(?:\.[a-zA-Z]{2,})(?:\/\S*)?$ |
URLs HTTP/HTTPS básicas |
| Dirección IPv4 | ^(?:\d{1,3}\.){3}\d{1,3}$ |
Solo formato, no valida rangos |
| IPv4 (estricto) | ^(?:(?: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]?)$ |
Valida rango 0-255 |
| Fecha (AAAA-MM-DD) | ^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$ |
Formato ISO 8601 |
| Hora (24 horas) | ^(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d)?$ |
HH:MM o HH:MM:SS |
| Teléfono (EE.UU.) | ^\+?1?[-.\s]?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$ |
Formato flexible |
| Color Hex | ^#(?:[0-9a-fA-F]{3}){1,2}$ |
Códigos hex de 3 o 6 dígitos |
| Tarjeta de Crédito | ^\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}$ |
Solo formato, usa Luhn para validación |
| Nombre de Usuario | ^[a-zA-Z0-9_-]{3,16}$ |
3-16 caracteres, alfanumérico más _ y - |
| Slug | ^[a-z0-9]+(?:-[a-z0-9]+)*$ |
Minúsculas amigables para URL con guiones |
Validación de Contraseña
La validación de contraseña requiere verificar múltiples condiciones simultáneamente. Las aserciones de búsqueda anticipada hacen esto posible sin lógica compleja.
// Contraseña fuerte: 8+ caracteres, mayúscula, minúscula, dígito, carácter especial
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/
// Desglosándolo:
// (?=.*[a-z]) - al menos una letra minúscula
// (?=.*[A-Z]) -