Expresiones regulares
Probar expresiones regulares online
Escribe la expresión y ve las coincidencias resaltadas sobre el texto al momento, con sus grupos. Y, sobre todo, con un panel que te explica tu propia expresión pieza a pieza, en lenguaje llano.
Ni la expresión ni el texto de prueba salen de tu equipo.
Por qué importa que el texto de prueba no se suba
Lo que se pega en un probador de expresiones no suele ser un ejemplo inventado: es un trozo de registro de producción, una exportación con datos de clientes, el cuerpo de una respuesta real o una lista de direcciones de correo. Se pega porque hace falta el caso real para saber si el patrón funciona. Aquí eso se queda en tu pestaña: incluso el hilo aparte donde se ejecutan las expresiones vive dentro de la misma página.
Cómo funciona, en 3 pasos
-
Escribe la expresión
O elige una de la biblioteca: viene con su texto de ejemplo, con casos que encajan y casos que no, para que veas la diferencia de un vistazo.
-
Mira el resaltado
Las coincidencias se pintan sobre el texto mientras escribes. Debajo, cada una con su posición y sus grupos, numerados y con nombre.
-
Entiéndela o sustitúyela
La pestaña de explicación desmonta la expresión pieza a pieza. La de sustituir aplica un reemplazo con referencias a grupos sobre todo el texto.
Para qué la usa la gente
- Entender una expresión heredadaAparece un patrón de treinta caracteres en el código y nadie sabe qué valida. El panel de explicación lo desmonta pieza a pieza.
- Extraer datos de un registroSacar las direcciones IP, las fechas o los códigos de error de un volcado, con los grupos separados y listos para copiar.
- Validar un formularioProbar el patrón contra los casos reales —incluidos los raros— antes de meterlo en el campo y descubrir que rechaza a un cliente.
- Reescribir en loteCambiar el formato de mil fechas o reordenar campos con una sustitución que usa los grupos, y ver el resultado antes de aplicarlo.
- Auditar un patrón peligrosoComprobar si esa expresión del validador puede colgarse con la cadena adecuada, que es una causa real de caídas.
- Aprender de verdadEscribir algo, ver qué hace cada trozo y por qué coincide donde coincide, en lugar de copiar un patrón de internet y cruzar los dedos.
El retroceso catastrófico, y por qué esta página no se cuelga
Hay una forma de escribir expresiones regulares que puede tumbar un servicio entero, y casi nadie que las escribe la conoce. Ocurre cuando algo que se repite está metido dentro de otra cosa que también se repite: (a+)+, (\d+)*, (\s*\w+)*. Mientras el texto encaja no pasa nada. El problema llega con un texto que casi encaja y falla al final: entonces el motor prueba todas las maneras posibles de repartir esos caracteres entre las dos repeticiones, y son exponenciales.
La cifra sorprende: con (a+)+$ y treinta caracteres, en la prueba que hicimos al construir esta herramienta el motor tardó más de diez segundos. Con cuarenta ya son horas. Y no es una curiosidad de laboratorio: es una causa habitual de caídas reales, porque basta con que alguien envíe la cadena adecuada a un formulario validado con un patrón así.
Aquí eso se ataca por dos lados. Primero, se analiza la forma de la expresión antes de ejecutarla y se avisa señalando el trozo culpable — sin dar la lata con las expresiones corrientes: el patrón de correo, el de fecha o el de IP no disparan ningún aviso. Y segundo, y esto es lo que de verdad protege: las búsquedas se ejecutan en un hilo aparte del navegador. Mientras un motor de expresiones trabaja, el hilo que lo ejecuta está bloqueado del todo: no hay temporizador ni botón de cancelar que llegue a ejecutarse. Un hilo aparte sí se puede matar desde fuera, y eso es lo que se hace si no contesta en poco más de un segundo. Cualquier página que prometa un límite de tiempo sin ejecutar en un hilo aparte, sencillamente no lo tiene.
Es el motor de JavaScript, y eso importa
Esta herramienta usa el motor de expresiones del navegador, que es el de JavaScript. Casi todo lo que pruebes aquí funcionará igual en otros lenguajes, pero hay diferencias que muerden justo cuando copias el patrón a otro sitio:
- Los cuantificadores posesivos (
a++) y los grupos atómicos ((?>…)) existen en Java, PCRE y .NET, pero no en JavaScript. Si los ves en un patrón que te dieron, aquí no significan lo mismo. - Las banderas se escriben aparte. Lo que aquí son botones, en Python es
re.IGNORECASEo un(?i)al principio del patrón. \dy\wno cubren lo mismo. En Python,\dincluye por defecto las cifras de otros alfabetos y\wlas letras acentuadas; en JavaScript son solo ASCII salvo que uses la banderaucon\p{…}.- Los grupos con nombre se escriben
(?<nombre>…)aquí y en .NET, pero(?P<nombre>…)en Python. - La mirada hacia atrás de longitud variable funciona en .NET y en JavaScript moderno, pero el módulo
rede Python la rechaza. - La bandera global guarda estado. En JavaScript, una expresión con
grecuerda por dónde iba entre llamadas, así que reutilizar el mismo objeto en un bucle da resultados alternos que parecen aleatorios. Es la rareza que más quebraderos de cabeza causa.
Guía rápida de sintaxis
| Se escribe | Significa | Ejemplo |
|---|---|---|
. | cualquier carácter salvo el salto de línea | a.c encaja con «abc», «a c» |
\d \w \s | cifra · letra, cifra o guion bajo · espacio en blanco | \d\d encaja con «42» |
\D \W \S | lo contrario de las anteriores | \S+ una palabra sin espacios |
[abc] | uno de esos caracteres | [aeiou] una vocal |
[^abc] | cualquiera menos esos | [^0-9] algo que no es cifra |
[a-z] | un rango | [a-zA-Z0-9] |
* + ? | cero o más · una o más · opcional | colou?r encaja con las dos grafías |
{2} {2,} {2,5} | exactamente · al menos · entre | \d{5} un código postal |
+? *? | perezoso: lo mínimo, no lo máximo | <.+?> una etiqueta, no toda la línea |
^ $ | principio y final (de línea con la bandera m) | ^\d+$ solo cifras |
\b | borde de palabra | \bcasa\b no encaja en «casado» |
(…) | grupo que se guarda | (\d{4})-(\d{2}) |
(?:…) | agrupa sin guardar | (?:ab)+ |
(?<n>…) | grupo con nombre | (?<anio>\d{4}) |
a|b | una cosa u otra | gato|perro |
(?=…) (?!…) | lo que sigue tiene que estar · no puede estar | (?=.*\d) hay una cifra en alguna parte |
\. \/ | el carácter literal, sin su significado | \. un punto de verdad |
La explicación es lo que convierte esto en aprender
Probar una expresión te dice si funciona. No te dice por qué. Por eso la pestaña de explicación desmonta el patrón pieza a pieza y traduce cada una a una frase: qué es \b, qué guarda un grupo, en qué se diferencia + de +?, qué significa esa mirada hacia delante que copiaste. Las piezas van indentadas según lo metidas que estén en paréntesis, así que la estructura se ve además de leerse.
Ese desglose se apoya en un analizador propio, y de un analizador es fácil fiarse de más: si se salta un trozo, la explicación mentiría con toda la confianza del mundo. La comprobación que lo impide es sencilla y dura: pegar el texto de todas las piezas tiene que devolver exactamente la expresión de partida. Si sobra o falta un solo carácter, el análisis está mal. Está comprobado con la biblioteca entera y con tres mil expresiones generadas al azar.
Sobre validar correos con una expresión regular
Es la petición número uno y merece una advertencia. La norma que define las direcciones de correo admite cosas que nadie espera: comillas, comentarios entre paréntesis, direcciones IP entre corchetes. La expresión que las acepta todas ocupa miles de caracteres, y aun así no comprueba lo único que importa: si el buzón existe.
Lo sensato —y lo que hace el patrón de la biblioteca— es quedarse en algo simple: hay una arroba, hay algo delante, hay algo detrás con un punto. Y confirmar de verdad enviando un correo con un enlace. Rechazar la dirección válida de un cliente molesta mucho más que aceptar una falsa que jamás se confirmará.
Si lo que necesitas es limpiar el texto antes de pasarle la expresión —quitar espacios dobles, unir líneas partidas de un PDF—, eso lo hace el conversor de mayúsculas, que trae un panel de limpieza. Y si estás depurando una respuesta de API, el formateador de JSON te la deja legible primero.
Preguntas frecuentes
¿Qué es el retroceso catastrófico y por qué me avisáis?
Es la forma que tiene una expresión de colgar un programa entero. Ocurre cuando algo que se repite está dentro de otra cosa que también se repite, como (a+)+. Con un texto que casi encaja y falla al final, el motor prueba todas las reparticiones posibles, y son exponenciales.
No es teórico: es una causa habitual de caídas reales, porque basta con que alguien envíe la cadena adecuada a un formulario validado así. Aquí se detecta la forma antes de ejecutarla y se te señala el trozo culpable.
¿Por qué la herramienta no se congela con esas expresiones?
Porque no las ejecuta en la misma página. Mientras el motor trabaja, el hilo que lo ejecuta está bloqueado del todo: no hay temporizador ni botón de cancelar que llegue a ejecutarse.
Por eso las búsquedas van a un hilo aparte del navegador, que sí se puede matar desde fuera. Si no contesta en poco más de un segundo, se termina y se te dice que la expresión no acaba. Cualquier página que prometa un límite de tiempo sin hacer esto, no lo tiene.
¿Sirve la expresión que pruebo aquí para Python o .NET?
A menudo sí, pero con trampas. Los cuantificadores posesivos y los grupos atómicos existen en Java, PCRE y .NET pero no en JavaScript. Las banderas en Python se escriben aparte. \d y \w cubren más cosas en Python por defecto.
Los grupos con nombre son (?<n>…) aquí y (?P<n>…) en Python. Y la mirada atrás de longitud variable la rechaza el módulo re. Prueba siempre el patrón también en el destino.
¿Por qué mi expresión de correo rechaza direcciones válidas?
Porque validar correos con una expresión es más feo de lo que parece: la norma admite comillas, comentarios y direcciones IP entre corchetes. La expresión completa ocupa miles de caracteres y aun así no comprueba si el buzón existe.
Lo práctico es quedarse en algo simple —hay arroba, hay algo delante y algo detrás con un punto— y confirmar enviando un correo. Rechazar a un cliente real molesta mucho más que aceptar una dirección que nunca se confirmará.
¿Qué diferencia hay entre (…) y (?:…)?
El primero agrupa y guarda lo que coincidió, para verlo en la tabla o usarlo como $1 al sustituir. El segundo agrupa sin guardar nada.
Usa el que no captura siempre que solo necesites agrupar: mantiene los números de los demás grupos en su sitio —evitando el clásico despiste de que $2 pase a ser $3— y le ahorra trabajo al motor. Y si el grupo te importa, dale nombre con (?<nombre>…).
¿Qué significa que un cuantificador sea perezoso?
Por defecto son glotones: se quedan con todo lo que puedan. Por eso <.+> sobre «<a> y <b>» coincide con la línea entera en vez de con cada etiqueta.
Añadiendo una interrogación, <.+?>, coge lo mínimo y devuelve las dos etiquetas por separado. Es la corrección más frecuente cuando una expresión captura de más.
¿Se sube mi texto de prueba a algún servidor?
No. La expresión y el texto se quedan en tu navegador; hasta el hilo aparte vive dentro de la misma página. No hay cuentas ni base de datos, y al recargar no queda nada. Carga la página, desconecta internet y compruébalo.
¿Por qué la bandera global da resultados raros en mi código?
Porque en JavaScript una expresión con g recuerda por dónde iba entre llamadas. Si reutilizas el mismo objeto con test en un bucle, la segunda llamada empieza donde acabó la primera: verdadero, falso, verdadero, falso.
Aquí no te afecta porque la herramienta reinicia esa posición en cada pasada, pero conviene saberlo al llevarte el patrón al código.