Expresiones regulares: coincidencia de patrones sin miedo
Al finalizar este tema
Podrás leer la sintaxis básica de las expresiones regulares, escribir patrones para correos electrónicos, números de teléfono y fechas, e interpretar qué hace cada expresión regular.
¿Por qué parecen tan intimidantes?
En un formulario de registro, necesitas validar el formato de un correo electrónico. Si lo haces con una sentencia if:
function isEmail(str) {
if (!str.includes("@")) return false;
const parts = str.split("@");
if (parts.length !== 2) return false;
if (parts[0].length === 0) return false;
if (!parts[1].includes(".")) return false;
// ... hay más
}Se puede hacer en una sola línea con una expresión regular:
const isEmail = str => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(str);Se ha vuelto más corto, pero también más difícil de leer. La razón por la que las expresiones regulares resultan intimidantes es su sintaxis compacta. Sin embargo, si aprendes unos pocos símbolos, podrás leer y escribir la mayoría de los patrones.
Sintaxis esencial en 5 minutos
. Un carácter cualquiera
\d Dígito (0-9)
\w Carácter de palabra (a-z, A-Z, 0-9, _)
\s Espacio en blanco (espacio, tabulador, salto de línea)
[abc] a, b o c
[^abc] Cualquier carácter salvo a, b y cFrecuencia:
* Cero o más veces
+ Una o más veces
? Cero o una vez
{3} Exactamente tres veces
{2,5} De dos a cinco vecesUbicación:
^ Inicio de la cadena
$ Final de la cadenaEsto es todo. Con la combinación de estos símbolos, se puede representar casi cualquier patrón.
5 patrones prácticos
1. Número de teléfono (010-1234-5678)
const phoneRegex = /^010-\d{4}-\d{4}$/;
phoneRegex.test("010-1234-5678"); // true
phoneRegex.test("02-123-4567"); // false\d{4} es "4 dígitos".
2. Contraseña (mínimo 8 caracteres, incluyendo números)
const pwRegex = /^(?=.*\d).{8,}$/;
pwRegex.test("hello123"); // true
pwRegex.test("helloworld"); // false (no contiene dígitos)
pwRegex.test("hi1"); // false (menos de 8 caracteres)(?=.*\d) es una búsqueda anticipada. Solo verifica si hay un número en algún lugar, pero no lo consume realmente.
3. Eliminación de etiquetas HTML
const stripped = "<b>Hola</b>, mundo".replace(/<[^>]+>/g, "");
// "Hola, mundo"<[^>]+> significa "empieza por <, contiene uno o más caracteres que no son > y termina en >".
4. Extracción de fecha (YYYY-MM-DD)
import retext = "La reunión está prevista para 2026-07-05. La fecha límite es 2026-08-01."dates = re.findall(r'\d{4}-\d{2}-\d{2}', text)# ['2026-07-05', '2026-08-01']5. Grupos de captura: extracción parcial
import rematch = re.search(r'(\d{4})-(\d{2})-(\d{2})', "Hoy es 2026-07-05")year, month, day = match.group(1), match.group(2), match.group(3)# '2026', '07', '05'La parte encerrada entre paréntesis () es un grupo. Se puede extraer mediante group(1) y group(2), respectivamente.
Cómo leer expresiones regulares
/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/Analicemos esto:
^ Inicio de la cadena
[A-Za-z0-9._%+-]+ Uno o más caracteres alfanuméricos o especiales (parte local)
@ Arroba
[A-Za-z0-9.-]+ Uno o más caracteres alfanuméricos, puntos o guiones (dominio)
\. Punto escapado
[A-Za-z]{2,} Dos o más letras (TLD: com, es, ...)
$ Final de la cadenaSe puede leer de izquierda a derecha, token por token.
Errores comunes
// ❌ Coincidencia codiciosa: captura la más larga
"<b>negrita</b> e <i>itálica</i>".match(/<.+>/);
// "<b>negrita</b> e <i>itálica</i>" — coincide con todo
// ✅ Coincidencia no codiciosa: captura la más corta
"<b>negrita</b> e <i>itálica</i>".match(/<.+?>/);
// "<b>" — coincide solo con la primera etiqueta
// ✅ O una clase de caracteres negada
"<b>negrita</b> e <i>itálica</i>".match(/<[^>]+>/);
// "<b>"+ y * son, por defecto, codiciosos (greedy). Intentan capturar la mayor cantidad posible. Al añadir ?, se vuelven perezosos (lazy) y capturan lo mínimo necesario.
Las expresiones regulares no son una solución universal
Lo que no se debe hacer con expresiones regulares:
- Parsing de HTML/XML: Las etiquetas anidadas no se pueden procesar correctamente con expresiones regulares. Utilice un parser DOM.
- Validación de sintaxis compleja: Para JSON, sintaxis de lenguajes de programación, etc., se requiere un parser.
- Procesamiento masivo donde el rendimiento es crítico: Tenga cuidado con la vulnerabilidad ReDoS (denegación de servicio por expresiones regulares).
Las expresiones regulares son más potentes cuando "el patrón es simple y la entrada es de una sola línea".
Idea clave: Con solo conocer
\d(números),+(uno o más) y[](clases de caracteres), se cubre el 80% de los patrones en el mundo real. Aunque parezcan intimidantes, basta con leerlas de izquierda a derecha, token por token.