Guía rápida de Regex gratuita

Guía de referencia interactiva para expresiones regulares.

Prueba de patrones en directo

Probar un patrón

Ninguna coincidencia

Cómo usar

  1. Explora las categorías de patrones o usa la barra de búsqueda para encontrar un patrón preciso.
  2. Introduce una expresión regular en el campo «Probar un patrón» y un texto de ejemplo en «Texto de prueba».
  3. Activa/desactiva los flags (global, insensible a mayúsculas, multilínea) y ve las coincidencias resaltadas al instante.

Preguntas frecuentes

¿Qué es una expresión regular?

Una expresión regular (regex o regexp) es un patrón que sirve para buscar, encontrar y reemplazar texto. Usa caracteres y una sintaxis especiales para definir las cadenas que se buscan.

¿Para qué sirven los flags?

Global (g) busca todas las coincidencias. Insensible a mayúsculas (i) ignora la caja de las letras. Multilínea (m) hace que ^ y $ coincidan con los límites de línea en lugar de los límites de cadena.

¿Puedo usar esta chuleta en mi código?

¡Sí! Cuando hayas probado un patrón y verificado que funciona, copia el patrón regex directamente en tu código JavaScript, Python o cualquier otro lenguaje.

Una breve historia del lenguaje de patrones

Las expresiones regulares empezaron como un trozo de informática teórica. Stephen Kleene definió los «conjuntos regulares» en un artículo de 1956 sobre redes neuronales; Ken Thompson las metió en Unix en 1968 con grep. La biblioteca regex open-source de Henry Spencer (mediados de los 80) fue la base de muchas implementaciones posteriores. Larry Wall extendió la sintaxis dramáticamente en Perl, y sus «expresiones regulares compatibles con Perl» (PCRE) se convirtieron en el estándar de facto que la mayoría de los lenguajes modernos siguieron. Hoy hay varios sabores de regex estrechamente relacionados pero sutilmente distintos, y un patrón que funciona en un motor no siempre funciona idénticamente en otro.

El motor en el que vive tu patrón

La misma sintaxis puede significar cosas distintas en motores distintos. Las grandes familias:

El probador interactivo de esta chuleta corre en JavaScript, así que el patrón lo evalúa el motor JS del navegador. Los patrones que funcionan aquí pueden comportarse de forma distinta en Python o PHP. La mayoría de las diferencias están en funcionalidades avanzadas (lookbehinds, Unicode property escapes, backreferences) más que en la sintaxis básica.

Los bloques de construcción centrales

Casi todo patrón regex se construye a partir de estos elementos:

Patrones que merece la pena memorizar

Un puñado de patrones aparecen tan a menudo que merece la pena tenerlos en la cabeza:

UsoPatrón
Email (básico)^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
URLhttps?://[^\s]+
Número de teléfono de EE.UU.\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}
Fecha ISO (YYYY-MM-DD)\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])
Dirección IPv4 (sin validación de octeto)\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b
Color hex^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
Espacio en blanco al inicio/final de línea^\s+|\s+$
Múltiples espacios consecutivos\s{2,}

Una nota sobre regex de email: la validación completa RFC 5322 necesita una regex monstruo de 6.000 caracteres. La forma simple anterior acepta el 99% de las direcciones de email reales y no rechaza ninguna legítima; en producción, envía un email de confirmación en lugar de intentar validar perfectamente la sintaxis.

Codicioso vs perezoso: una sorpresa común

Por defecto, los cuantificadores son codiciosos: coinciden con tanto como sea posible mientras el patrón global siga pudiendo coincidir. Así que <.+> contra <a>text</a> coincide con todo, no sólo con <a>, porque .+ agarra todo lo que puede. Para coincidir con la cadena más pequeña posible, añade ? al cuantificador: <.+?> coincide con <a> y luego con </a> por separado. La elección codicioso/perezoso es una de las fuentes más comunes de bugs «¿por qué mi regex no coincide con lo que esperaba?».

Backtracking catastrófico y ReDoS

Algunos patrones regex pueden tardar tiempo exponencial en fallar sobre ciertos inputs, una clase de vulnerabilidad de denegación de servicio llamada ReDoS (Regular Expression Denial of Service). Los culpables clásicos son los cuantificadores anidados como (a+)+ o (a|aa)+ aplicados a una cadena larga de as seguida de un carácter que no encaja. El motor prueba cada forma posible de partir la cadena antes de rendirse, y el número de formas es exponencial.

Incidentes del mundo real: la caída de Cloudflare en 2019 la disparó una regex desplegada en una regla WAF que backtrackeó catastróficamente sobre ciertos inputs. Stack Overflow tuvo un incidente similar en julio de 2016: una regex de post-trim (^[\s‌]+|[\s‌]+$) chocó con un backtracking exponencial en un único comentario que contenía aproximadamente 20.000 caracteres de espacio en blanco consecutivos y tumbó el sitio durante 34 minutos. Hábitos defensivos: evita cuantificadores anidados, prefiere atomic groups ((?>...)) donde estén soportados, y considera usar RE2 / motores de tiempo lineal para input no confiable.

Peculiaridades por lenguaje que conviene conocer

Cuándo NO usar regex

La famosa frase de Jamie Zawinski de 1997: «Some people, when confronted with a problem, think 'I know, I'll use regular expressions.' Now they have two problems.»

Errores comunes

  1. Olvidarse de escapar caracteres especiales. ., *, ?, +, (, ), [, ], {, }, \, ^, $, |, / tienen todos significados especiales. Para hacer match literal, prefíjalos con barra invertida.
  2. Cuantificadores codiciosos consumiendo demasiado. Añade ? para matching perezoso cuando quieras la coincidencia más pequeña posible.
  3. Olvidarse del flag global y preguntarse por qué sólo aparece la primera coincidencia. El String.prototype.match() de JavaScript devuelve sólo la primera coincidencia sin el flag g.
  4. Backtracking catastrófico en inputs largos. Cuantificadores anidados como (a+)+ pueden colgarse en ciertos inputs. Prueba con casos límite.
  5. Suponer que la misma regex se comporta igual en cada lenguaje. Lookbehinds, escapes Unicode y atajos de clase de caracteres varían todos.
  6. Intentar validar emails demasiado estrictamente. La regex técnicamente correcta RFC 5322 es inmantenible; una regex simple más email-de-confirmación-al-registro es el patrón que funciona.
  7. Usar regex sobre HTML, JSON o CSV. Usa un parser apropiado; el tiempo que ahorras al principio lo pierdes en bugs.

Más preguntas frecuentes

¿Por qué mi patrón funciona aquí pero falla en mi código?

La causa más común son las diferencias entre motores. El RegExp de JavaScript no soporta algunas funcionalidades que PCRE sí (y viceversa). Trampas comunes: lookbehinds añadidos tarde a JS (ES2018), la sintaxis de grupos con nombre difiere ligeramente, los Unicode property escapes necesitan el flag u, y las clases de carácter POSIX como [[:alpha:]] están casi ausentes en JS. Prueba en el motor en el que vayas a desplegar.

¿Hay una forma «global» de hacer match a través de múltiples líneas?

Dos flags trabajan juntos. El flag m (multilínea) hace que ^ y $ coincidan con el inicio y el final de cada línea en vez de con la cadena entera. El flag s (dotall) hace que . también coincida con caracteres de salto de línea. Combinado con g para global, puedes escribir patrones que abarcan líneas y encuentran cada coincidencia: /^foo.+$/gms.

¿Mis patrones y mi texto de prueba se envían a algún sitio?

No. El matching de patrones usa el motor RegExp JavaScript integrado en el navegador; nada se sube a ningún servidor. Esto importa cuando estás probando patrones contra datos de log de producción reales, respuestas de API internas o contenido sensible.

¿Debería aprender lookbehinds?

Útiles pero no esenciales. Los lookbehinds te permiten hacer match con texto precedido por algo sin incluir ese «algo» en la coincidencia. Ejemplo: (?<=\$)\d+ coincide con dígitos detrás de un signo de dólar sin consumir el signo de dólar. Están soportados en PCRE, JavaScript moderno (ES2018+) y el módulo regex de Python. Si estás escribiendo patrones portables, comprueba primero el motor de destino.

¿Por qué usar (?:...) en lugar de (...)?

Los grupos no capturadores ((?:...)) son ligeramente más rápidos, no toman ranura en el array de capturas y mantienen tus resultados de match limpios. Úsalos cuando necesites agrupación para alternancia o cuantificación pero no necesites extraer el texto coincidente. (http|https):// crea una captura que quizá no necesitas; (?:http|https):// no.

¿Cuál es la forma correcta de hacer match con caracteres Unicode?

En JavaScript, añade el flag u y usa Unicode property escapes: /\p{Letter}+/gu coincide con secuencias de letras en cualquier escritura. Sin el flag u, \w sólo coincide con caracteres de palabra ASCII. El módulo re de Python es Unicode-aware por defecto en Python 3. Java necesita Pattern.UNICODE_CHARACTER_CLASS. La mayoría de los motores tienen alguna forma de ser Unicode-aware; consulta la documentación del tuyo.

Herramientas relacionadas

Formateador y validador JSON gratuito en línea Codificador / Decodificador de URL gratuito Convertidor de mayúsculas y minúsculas