Expresiones regulares en la práctica

Una expresión regular describe un conjunto de cadenas: \d{4}-\d{2}-\d{2} reconoce fechas escritas como 2025-03-14, \d{8}[A-Z] un DNI. Los paréntesis crean grupos de captura, que la sustitución puede reutilizar con $1, $2 o por nombre si el grupo lo tiene.

Los flags cambian el comportamiento: g busca todas las coincidencias en lugar de la primera, i ignora mayúsculas y minúsculas, m hace que ^ y $ valgan en cada línea, s permite que el punto coincida con saltos de línea, u activa clases Unicode como \p{L}. Sin g, la sustitución cambia solo la primera aparición.

Algunos patrones, como (a+)+$ o (\w+\s?)*$, prueban un número exponencial de combinaciones sobre un texto que casi coincide y pueden bloquear un navegador o un servidor: es el ReDoS. Aquí la prueba se ejecuta en un proceso aparte y se detiene al cabo de un segundo, así la página sigue usable y te avisa del problema.

Errores frecuentes

  • Olvidar duplicar las barras invertidas cuando la regex va dentro de una cadena en el código: aquí se escribe \d, en una cadena JavaScript "\\d".
  • Usar .* donde hace falta .*?: el cuantificador codicioso se lleva todo hasta la última aparición posible.
  • Anidar cuantificadores como (a+)+ o (a|a)*: son la causa más habitual de backtracking catastrófico.

Preguntas frecuentes

¿Qué motor de expresiones regulares usa?

El de JavaScript (ECMAScript) de tu navegador. Es muy parecido a PCRE, el de PHP, pero faltan algunas funciones, como los grupos atómicos y los cuantificadores posesivos.

¿Cómo uso un grupo en la sustitución?

Con $1, $2… para los grupos numerados, $ seguido del nombre entre ángulos para los que tienen nombre y $& para la coincidencia completa. Un dólar literal se escribe $$.

¿Se envía a algún sitio el texto que escribo?

No: todo ocurre en el navegador. Patrón y texto solo pasan a la dirección de la página, para poder compartirla, y solo si son cortos.

Cómo funciona este cálculo

El patrón se compila con new RegExp(patrón, flags) y se aplica con String.prototype.matchAll, siempre con el flag g añadido para recorrer el texto; sin g en la petición solo se conserva la primera coincidencia. La sustitución usa String.prototype.replace con los flags elegidos. La ejecución se hace en un Web Worker, que se termina si no responde en 1 segundo; se listan como máximo 1000 coincidencias.