Saltar al contenido
Tecnología

Probador de expresiones regulares

Prueba y depura expresiones regulares con resaltado, grupos y sustitución, sin que una expresión mal hecha cuelgue la página.

Se escribe sin las barras: pon \d+ y no /\d+/g. Las marcas se eligen abajo.

Marcas
147 / 100.000

Se procesa en tu navegador. Puedes pegar datos reales sin que salgan de este equipo.

Coincidencias

Escribe una expresión para ver qué encuentra.

Se procesa en tu navegador. La expresión y el texto se procesan en un worker de tu navegador. Puedes pegar registros reales sin que salgan de este equipo.

Para qué sirve

Una expresión regular describe un patrón de texto: «cuatro dígitos, un guion, dos dígitos» en lugar de una fecha concreta. Sirve para buscar, validar, extraer y sustituir, y está en casi todos los lenguajes con la misma sintaxis, así que lo que aprendes aquí vale igual en JavaScript, en Python o en el buscador de tu editor.

Escribirlas es fácil de empezar y difícil de acertar a la primera. Por eso se prueban: se escribe la expresión, se pega un texto representativo y se mira qué casa y qué no antes de llevarla al código.

Esta herramienta ejecuta la expresión **fuera del hilo principal**, con un plazo de segundo y medio. Suena a detalle técnico y es lo que evita que la página se quede colgada cuando escribes sin querer una expresión patológica: en lugar de una pestaña bloqueada, sale un aviso.

Cómo se calcula

El motor recorre el texto intentando encajar el patrón en cada posición. Cuando una alternativa falla, retrocede y prueba la siguiente: eso es el backtracking, y es lo que hace potentes a las expresiones regulares y también lo que puede volverlas peligrosas.

Con cuantificadores anidados, el número de combinaciones que hay que probar crece de forma exponencial con la longitud del texto. La expresión «(a+)+b» sobre treinta aes seguidas obliga al motor a explorar más de mil millones de caminos antes de rendirse. Se llama backtracking catastrófico.

JavaScript no tiene forma de poner un límite de tiempo a una expresión regular: una vez arranca, no cede el control ni atiende a ningún temporizador. La única manera de recuperarse es ejecutarla en un proceso aparte al que sí se pueda matar desde fuera, y eso es un web worker.

Conviene un matiz, porque casi nadie lo cuenta: el motor de Chrome ya se defiende de una parte de estos casos. Cuando la expresión no lleva retrovisores ni lookarounds, puede ejecutarla con un algoritmo de tiempo lineal, y ejemplos de manual como (a+)+b se resuelven al instante. Lo que no puede linealizar es todo lo que lleve \1 o (?<=…), y ahí el cuelgue sigue siendo real. En Node, sin esa red, se cuelga hasta el ejemplo de manual.

\d{4}-\d{2}-\d{2}

Una fecha en formato ISO: cuatro dígitos, guion, dos, guion, dos.

(?<usuario>\w+)@(?<dominio>[\w.]+)

Grupos con nombre: se recuperan con $<usuario> al sustituir, en lugar de contar paréntesis.

(a+)+b   ← evítalo

Cuantificador dentro de cuantificador. Sobre un texto que no casa, tarda un tiempo exponencial.

Ejemplo resuelto

Extraer los correos de un texto

Expresión
\b(\w+)@(\w+)\.(com|es|org)\b
Marcas
g
  1. \b marca un límite de palabra: evita casar la parte final de «xxhola@…».
  2. (\w+) captura el usuario en el grupo 1: letras, dígitos y guion bajo.
  3. @ y \. son literales. El punto va escapado porque sin barra significa «cualquier carácter».
  4. (com|es|org) captura el dominio de primer nivel en el grupo 3, limitado a esos tres.
  5. La marca g hace que se recorra todo el texto en lugar de parar en la primera.

Sobre un texto con tres direcciones, devuelve las tres con su usuario y su dominio separados en grupos.

Las marcas y para qué sirve cada una

Van después de la barra de cierre en la notación habitual: /patrón/gi. Aquí se eligen con los botones.

MarcaQué haceCuándo la quieres
gBusca todas las coincidenciasCasi siempre, salvo que solo te interese la primera
iNo distingue mayúsculasAl buscar palabras escritas por personas
m^ y $ marcan cada líneaAl procesar texto de varias líneas
sEl punto casa saltos de líneaAl capturar bloques que cruzan líneas
uModo unicodeCon emojis o acentos: hace que \w y los rangos se comporten
yPegajosaAl escribir un analizador que avanza posición a posición

Backtracking catastrófico: el fallo que tumba servidores

No es un caso de laboratorio. En 2019 una expresión regular mal construida dejó fuera de servicio a Cloudflare durante media hora, y el mismo patrón ha causado caídas en Stack Overflow y en varios proyectos grandes. Se le llama ReDoS cuando alguien lo provoca a propósito enviando una entrada preparada.

El patrón peligroso tiene una forma reconocible: un cuantificador dentro de otro, como (a+)+ o (\w*)*, o alternativas que pueden casar lo mismo, como (a|a)*. Si además el texto no llega a casar del todo, el motor prueba todas las combinaciones antes de rendirse.

La defensa práctica es escribir cuantificadores que no se solapen, acotar las repeticiones con {1,50} en lugar de + cuando sepas el máximo, y desconfiar de cualquier expresión que venga de fuera. Si validas entrada de usuario con una expresión regular, esa expresión es superficie de ataque.

Lo que una expresión regular no debería hacer

Analizar HTML o XML. No son lenguajes regulares: pueden anidarse hasta el infinito y ninguna expresión regular puede seguir esa estructura. Para eso está un analizador de verdad, como DOMParser en el navegador.

Validar correos electrónicos a rajatabla. La expresión que cumple el RFC 5322 completo ocupa varias líneas y aun así acepta direcciones que ningún servidor entrega. En la práctica basta con comprobar que hay una arroba con algo a cada lado y mandar un correo de confirmación.

Preguntas frecuentes

¿Por qué se ha detenido mi expresión por tiempo?

Porque ha entrado en backtracking catastrófico: el motor está probando una cantidad enorme de combinaciones y no va a terminar en un tiempo razonable. Casi siempre la causa es un cuantificador dentro de otro, como (a+)+ o (\w*)*. Prueba a quitar un nivel de anidamiento o a acotar las repeticiones con llaves.

¿Tengo que poner las barras al escribir la expresión?

No. Escribe solo el patrón: \d+ en lugar de /\d+/g. Las barras son la notación literal de JavaScript y las marcas se eligen con los botones de abajo, así que ponerlas haría que el motor las buscara como caracteres normales.

¿Cuál es la diferencia entre (…) y (?:…)?

Los paréntesis normales capturan: guardan lo que casan para que puedas recuperarlo como $1, $2 y así. Los de (?: agrupan sin capturar, que es lo que quieres cuando solo necesitas aplicar un cuantificador a un bloque. Además de dejar la lista de grupos más limpia, evitan trabajo al motor.

¿Sirve esta sintaxis en otros lenguajes?

En su mayor parte sí. El núcleo —clases, cuantificadores, grupos, anclas— es común a JavaScript, Python, Java, PHP y Go. Cambian los detalles: los grupos con nombre se escriben distinto en algunos, y el motor de Go no admite retrovisores. Lo que pruebes aquí funcionará casi igual en cualquiera de ellos.

¿El texto que pego se envía a algún servidor?

No. Tanto la expresión como el texto se procesan en tu navegador, en un web worker local. No hay ninguna petición de red, así que puedes pegar registros o datos reales sin que salgan de tu equipo.

Fuentes

Toda la información de esta página se refiere a: Probador de expresiones regulares.