Banco de pruebas de patrones · Gratis

Probador y depurador de regex

Escribe un patrón, pega el texto con el que realmente trabajas y mira cómo se ilumina cada coincidencia mientras escribes, con grupos de captura, grupos con nombre, posiciones, vista previa del reemplazo y errores de sintaxis explicados en lenguaje claro en lugar de con las palabras del propio entorno de ejecución.

El RegExp de tu propio navegador · No se sube nada
Informar de un problema

Espacio de trabajo de expresiones regulares

3 coincidencias, 3 grupos de captura. Primera coincidencia en el índice 9.

Patrón

Escríbelo sin las barras

O pega un literal completo como /\d+/gi y los flags vienen con él. Todo lo de abajo se recalcula con cada pulsación.

g

Compila. 3 grupos de captura (year, month y day) · el patrón tiene 70 caracteres.

Flags
Coincidencias en el texto de prueba
3

/\b(?<year>\d{4})-(?<month>0[1-9]|1[0-2])-(?<day>0[1-9]|[12]\d|3[01])\b/g sobre 114 caracteres.

Coincidencias
3
Grupos de captura
3
Grupos con nombre
3
Aciertos de ancho cero
0
Texto cubierto
26.3%
Tiempo de ejecución
–
Texto de prueba

El texto sobre el que se ejecuta el patrón

Las coincidencias se colorean mientras escribes. Las coincidencias contiguas alternan el tono y cada una lleva una línea en su borde izquierdo, para que dos aciertos que se tocan nunca parezcan uno.

114 / 100,000 caracteres · 4 líneas

Resultados

Todas las coincidencias, con sus posiciones y sus grupos de captura.

Coincidencia #1 · grupos de captura
del índice 9 al 19
  • $1year2026
  • $2month07
  • $3day27

Activa el flag d para ver dónde está cada grupo, no solo lo que contiene.

Patrones predefinidos

Patrones honestos sobre lo que detectan

Cada uno carga su patrón, sus flags, un reemplazo y un texto de ejemplo con los casos que rechaza a propósito.

Comprobaciones de forma

Patrones con anclas que comprueban si una línea entera tiene la forma correcta.

Encontrar cosas en un texto

Patrones sin anclas que extraen elementos de un texto corrido o de logs.

Reescritura

Patrones cuyo objetivo es la sustitución más que la búsqueda.

Guía rápida

Cada token, lo que significa y el ejemplo más pequeño que lo muestra

Sintaxis de JavaScript en concreto: las notas señalan los puntos en los que se separa de PCRE y de Python.

Clases de caracteres

Una posición en el texto y el conjunto de caracteres que pueden ocuparla.

.
Cualquier carácter excepto un salto de línea, salvo que el flag s esté activado./a.c/ coincide con "abc", "a-c", no con "a\nc"
[abc]
Cualquiera de los caracteres de la lista./[aeiou]/ en "rhythm" no encuentra nada
[^abc]
Cualquier carácter que no esté en la lista. El acento circunflejo debe ir primero./[^0-9]/ en "a1" coincide con "a"
[a-z]
Un rango, por orden de punto de código./[a-f0-9]/ es un dígito hexadecimal
\d \D
Un dígito ASCII, y cualquier cosa que no lo sea. \d es exactamente [0-9]; no incluye los dígitos arábigo-índicos ni los de ancho completo./\d{4}/ en "year 2026" coincide con "2026"
\w \W
Un carácter de palabra [A-Za-z0-9_], y su complemento. Las letras acentuadas no son caracteres de palabra./\w+/ en "café" coincide con "caf"
\s \S
Espacio en blanco (espacio, tabulación, salto de línea, salto de página, NBSP y los separadores de espacio Unicode), y su complemento./\s+/ condensa series de espacios
\p{…}
Una propiedad Unicode. Necesita el flag u; sin él, \p significa una "p" literal./\p{Lu}/u coincide con una letra mayúscula de cualquier escritura

Cuantificadores

Cuántas veces puede repetirse lo que va delante. Codiciosos por defecto; añade ? para hacerlos perezosos.

*
Cero o más. Siempre tiene éxito, y por eso /a*/g coincide en todas partes./ab*c/ coincide con "ac" y "abbbc"
+
Uno o más./\d+/ en "abc123" coincide con "123"
?
Cero o uno: el átomo es opcional./colou?r/ coincide con ambas grafías
{3}
Exactamente tres veces./\d{3}/ coincide con "555"
{2,}
Dos o más veces, sin límite superior./o{2,}/ en "ooooh" coincide con "oooo"
{2,4}
Entre dos y cuatro veces./a{2,4}/ en "aaaaa" coincide con "aaaa"
*? +? ?? {n,m}?
Las formas perezosas: toman lo mínimo posible y solo crecen si el resto del patrón falla./<.+?>/ en "<a><b>" coincide con "<a>", no con "<a><b>"

Anclas y límites

Aserciones de ancho cero. No consumen nada y solo preguntan por la posición.

^
Inicio del texto, o inicio de cualquier línea con el flag m./^ERROR/m encuentra cada línea que empieza por ERROR
$
Fin del texto, o fin de cualquier línea con el flag m./;$/m encuentra las líneas que terminan en punto y coma
\b
Un límite de palabra: entre un \w y un no-\w. Se define sobre caracteres de palabra ASCII, así que cae en mitad de la palabra en "naïve"./\bcat\b/ no coincide con "category"
\B
No es un límite de palabra./\Bcat/ coincide con el "cat" de dentro de "bobcat"

Grupos, alternancia, referencias

Capturar es lo que convierte una prueba en datos extraídos, y lo que cuesta memoria cuando no lo necesitabas.

(…)
Grupo de captura, numerado de izquierda a derecha según el paréntesis de apertura./(\d+)-(\d+)/ da dos grupos
(?:…)
Grupo sin captura. La misma agrupación, sin posición en el resultado./(?:ab)+/ repite "ab" y no captura nada
(?<name>…)
Grupo de captura con nombre, ES2018. Disponible como match.groups.name./(?<year>\d{4})/ y luego match.groups.year
|
Alternancia, probada de izquierda a derecha. Gana la primera rama que permite que todo el patrón tenga éxito./cat|category/ en "category" coincide con "cat"
\1
Referencia inversa: el texto exacto con el que ya coincidió el grupo 1./(\w+) \1/ encuentra una palabra repetida
\k<name>
Referencia inversa a un grupo con nombre./(?<q>['"]).*?\k<q>/ coincide con comillas equilibradas

Lookaround

Aserciones que inspeccionan el texto alrededor de la posición actual sin consumirlo.

(?=…)
Lookahead: lo que sigue debe coincidir./\d+(?= kg)/ en "80 kg" coincide con "80"
(?!…)
Lookahead negativo: lo que sigue no debe coincidir./\bfoo(?!bar)/ se salta "foobar"
(?<=…)
Lookbehind: lo que precede debe coincidir. ES2018 y, a diferencia de la mayoría de los motores, JavaScript permite que tenga longitud variable./(?<=£)\d+/ en "£40" coincide con "40"
(?<!…)
Lookbehind negativo: lo que precede no debe coincidir./(?<!un)happy/ se salta "unhappy"

Flags

Se fijan para la regex en su conjunto. JavaScript no tiene un modificador en línea (?i): el flag se aplica en todas partes o en ninguna.

g
Global: todas las coincidencias, y lastIndex se conserva entre llamadas a exec./a/g con matchAll
i
Sin distinguir mayúsculas de minúsculas./hello/i coincide con "HELLO"
m
Multilínea: ^ y $ coinciden en los saltos de línea. No afecta al punto./^\s*$/m encuentra líneas en blanco
s
Dot-all: . también coincide con los saltos de línea./<p>.*<\/p>/s abarca varias líneas
u
Modo Unicode: puntos de código, \p{…}, \u{…} y escapes estrictos./^.$/u coincide con un solo emoji
y
Fijo (sticky): coincide solo en lastIndex, sin avanzar.Los tokenizadores avanzan lastIndex a mano
d
Índices: match.indices contiene [start, end] para cada grupo.match.indices[1] localiza el grupo 1

Escapes y literales

Doce caracteres son especiales. Para buscar uno literalmente, ponle una barra invertida delante.

\. \* \+ \?
Los metacaracteres, tomados literalmente. El conjunto completo es . * + ? ^ $ { } ( ) | [ ] \/\d+\.\d+/ coincide con "3.14"
\\
Una barra invertida literal. En un literal de cadena se vuelve a duplicar: \\\\.new RegExp("\\\\d") es /\\d/
\n \r \t
Salto de línea, retorno de carro, tabulación./\r?\n/ divide con cualquiera de los dos finales de línea
\xFF
Un carácter por su código hexadecimal de dos dígitos./\x41/ coincide con "A"
\u00e9
Un carácter por su código hexadecimal de cuatro dígitos./\u00e9/ coincide con "é"
\u{1F600}
Un punto de código por encima de U+FFFF. Requiere el flag u./\u{1F600}/u coincide con un emoji
\0
El carácter NUL. No es un escape octal: esos no son válidos con u./\0/ coincide con U+0000

Este es el motor de tu navegador

El patrón va directo al constructor RegExp del entorno de ejecución, así que lo que ves es lo que harán Node y el navegador. El re de Python, PCRE, RE2 de Go y grep difieren: a veces en la sintaxis y a veces en lo que significa una sintaxis idéntica.

\d es [0-9] aquí, y no en todas partes

JavaScript mantiene \d, \w y \b en ASCII independientemente del flag u. Python y .NET amplían por defecto \d a todos los dígitos decimales Unicode, así que ٢٠٢٦ pasa allí y falla aquí. Pide \p{Nd} cuando quieras el significado amplio.

El anidamiento está fuera de alcance

Ninguna expresión regular puede reconocer paréntesis equilibrados, lo que descarta HTML, JSON y código fuente por mucho que crezca el patrón. El patrón predefinido de HTML de esta página se presenta a propósito como un vistazo rápido, no como un analizador.

Todo en esta página se ejecuta en tu navegador con la propia implementación de RegExp de tu navegador: ningún patrón, texto de prueba ni resultado se envía nunca a ninguna parte. Los límites se indican en lugar de darse por supuestos: hasta 100,000 caracteres de texto de prueba, 5,000 coincidencias y 250 ms de tiempo real por ejecución, tras lo cual la ejecución se detiene y lo indica. Una coincidencia de longitud cero siempre avanza el cursor un punto de código completo, así que un patrón como /a*/g termina en lugar de entrar en un bucle.

Cómo funciona

Un patrón, un texto y todo lo que el motor sabe de la pareja.

Una expresión regular es un programa diminuto, y cuesta depurarla porque se ejecuta de forma invisible: ves la respuesta, nunca el procedimiento. Esta página hace visible el procedimiento. Tu patrón lo compila el propio constructor RegExp del navegador, se ejecuta sobre tu texto con un límite de longitud, de número de coincidencias y de tiempo real, y el resultado se muestra coincidencia por coincidencia: dónde empieza y termina cada una, qué contiene cada grupo de captura, qué grupos no participaron en absoluto y qué produciría una sustitución. Como es el motor del entorno de ejecución y no una reimplementación, los resultados son los que obtendrá tu JavaScript. Siendo sinceros, no son los que obtendrán Python, PCRE, RE2 de Go o grep.

  1. 01

    Escribe el patrón y elige los flags

    Escribe el patrón sin las barras que lo rodean, o pega un literal completo como /\d+/gi y los flags llegan con él. Cada uno de los siete flags es un interruptor con su etiqueta en lugar de una letra que recordar, y un error de sintaxis se explica con una frase en vez de con la redacción del entorno de ejecución.

  2. 02

    Pega el texto con el que realmente trabajas

    Entrada real, no un ejemplo artificial: un fragmento de log, una columna de CSV, una página de prosa. Las coincidencias se resaltan mientras escribes, con tonos alternos para que dos coincidencias contiguas sigan siendo dos, y una coincidencia de ancho cero se dibuja como un marcador en lugar de desaparecer.

  3. 03

    Lee los grupos y luego prueba la sustitución

    Cada coincidencia muestra sus posiciones y cada grupo numerado y con nombre, incluidos los que no participaron. Cambia a Reemplazar para previsualizar una sustitución con $1, $<name>, $& y compañía expandidos, o a Dividir para ver qué hace String.split con el mismo patrón.

Hecho para depurar, no para hacer demostraciones

Lo que otros probadores pasan por alto: coincidencias vacías, grupos ausentes y patrones que se resisten.

Una búsqueda que no puede colgar la pestaña

Una coincidencia de longitud cero avanza el cursor un punto de código completo, así que /a*/g termina en lugar de entrar en un bucle infinito. Un presupuesto de tiempo real detiene una ejecución que ha empezado a atascarse y avisa de que el patrón hace un backtracking excesivo, en lugar de congelarse tras un indicador de carga que nunca termina.

Los grupos que no participaron se siguen mostrando

Con /(a)|(b)/ sobre "b", el grupo 1 es undefined y el grupo 2 contiene la coincidencia. Los probadores que descartan la posición vacía renumeran en silencio todo lo que viene después. Aquí la posición se mantiene, marcada como no participante, que es exactamente la distinción que rompe el código posterior.

Posiciones para cada grupo, no solo para la coincidencia

Activa el flag d y cada captura indica su propio índice de inicio y de fin, leído de match.indices. Sin él obtienes la posición de la coincidencia completa y tienes que volver a buscar el texto del grupo, lo que falla en cuanto el mismo texto aparece dos veces.

Una vista previa del reemplazo que expande los casos incómodos

$1, $<name>, $&, $` y $' y $$ se expanden aquí en lugar de describirse, incluida la regla de que $12 significa el grupo 12 cuando existe y el grupo 1 seguido de un "2" cuando no. El resultado se contrasta con lo que produce String.replace.

Errores de sintaxis traducidos a algo útil

"Invalid regular expression: /(/: Unterminated group" se convierte en "Se abrió un ( que nunca se cerró", con una nota de que un paréntesis literal necesita escaparse. Se reconocen unas quince familias de errores en las distintas redacciones que usan V8, JavaScriptCore y SpiderMonkey.

Diez patrones predefinidos que dicen lo que realmente detectan

El patrón de email se describe como la forma pragmática que atrapa erratas, no como una validación RFC 5322. El de IPv4 limita cada octeto a 255 y admite que aun así encontrará una dirección dentro de una cadena de versión. Cada patrón predefinido incluye un texto de ejemplo con los casos que rechaza.

Preguntas sobre regex

Codicioso frente a perezoso, backtracking catastrófico y dónde JavaScript se separa de PCRE.

¿Qué variante de regex prueba esta herramienta?+

La que ya se ejecuta en tu navegador. Esta página no incluye ningún motor: tu patrón se entrega al propio constructor RegExp del entorno de ejecución de JavaScript, y las coincidencias que ves son las que obtendrá tu código. Eso hace que los resultados sean exactos para JavaScript, TypeScript, Node, Deno y Bun. Para cualquier otra cosa solo son aproximados. El re de Python, PCRE en PHP y Perl, RE2 de Go, el crate regex de Rust, .NET, Java, grep, sed y ripgrep difieren, a veces en la sintaxis y a veces en lo que significa la misma sintaxis. Si el patrón va destinado a otro lenguaje, pruébalo allí antes de publicarlo.

¿Cuál es la diferencia entre los cuantificadores codiciosos y los perezosos?+

Un cuantificador codicioso toma todo lo que puede y luego devuelve caracteres de uno en uno hasta que el resto del patrón encaja. Uno perezoso (que se escribe añadiendo un signo de interrogación, así: *? +? ?? {n,m}?) toma lo mínimo posible y solo crece cuando se ve obligado. La demostración clásica es /<.+>/ sobre "<a><b>": el .+ codicioso se traga todo hasta el final, retrocede hasta el último ">" y devuelve "<a><b>" como una sola coincidencia. Cámbialo a /<.+?>/ y obtienes "<a>" y luego "<b>". Ninguno es más correcto; responden a preguntas distintas. La regla práctica es que el codicioso es la opción adecuada por defecto cuando el delimitador es único, y el perezoso cuando se repite.

¿Qué es el backtracking catastrófico?+

Es lo que ocurre cuando un patrón puede dividir el mismo texto de muchas formas distintas y al final la coincidencia falla. JavaScript busca coincidencias mediante backtracking, así que, ante un fallo, reintenta todas las combinaciones restantes antes de rendirse. El desencadenante de manual es una repetición dentro de otra repetición, como /(a+)+$/ sobre una larga serie de "a" seguida de una sola "b". Hay un número exponencial de formas de dividir 30 letras "a" en grupos de una o más, y el motor las prueba todas antes de concluir que el "$" no puede coincidir. Treinta caracteres tardan milisegundos; cuarenta tardan unas mil veces más. Las soluciones son hacer que las repeticiones interior y exterior no puedan coincidir con el mismo texto, sustituir un grupo cuantificado por una clase de caracteres o anclar el patrón para que el fallo se detecte pronto. Esta página analiza tu patrón en busca de esas formas y las señala antes de ejecutarlo.

¿Por qué el lookbehind llegó tan tarde a JavaScript?+

El lookahead estaba en el lenguaje desde el principio, pero el lookbehind no llegó hasta ES2018 (más de veinte años después), y hasta que Safari lo incorporó en 2023, un patrón que lo usara lanzaba un error de sintaxis en un navegador que muchos sitios aún tenían que admitir. El retraso se debió en parte a la ralentización general de la evolución del lenguaje entre el abandono de ES4 y ES6, y en parte a que el lookbehind es realmente más difícil de implementar: el motor tiene que buscar hacia atrás desde la posición actual. La implementación de JavaScript acabó siendo mejor que la mayoría, porque, a diferencia de PCRE, el re de Python y Java, permite lookbehind de longitud variable. /(?<=\$\d+ )item/ es válido aquí y esos motores lo rechazan de plano. Si un patrón tuyo tiene que funcionar en un entorno antiguo, la solución tradicional es capturar el contexto anterior en un grupo y descartarlo después.

¿Cuál es la diferencia entre los flags u y v?+

El flag u, de ES2015, pone el patrón en modo Unicode: los caracteres astrales, como los emoji, cuentan como una unidad en lugar de dos mitades UTF-16, \u{1F600} pasa a ser válido, se habilitan los escapes de propiedad \p{…} y los escapes sin significado se convierten en errores de sintaxis en lugar de ignorarse en silencio. El flag v, de ES2024, es un superconjunto que añade notación de conjuntos dentro de las clases de caracteres (diferencia con --, intersección con && y propiedades de cadenas de varios caracteres), de modo que puedes escribir [\p{Letter}--[a-z]] para decir "cualquier letra excepto una minúscula ASCII". Los dos flags son mutuamente excluyentes: una regex está en modo u o en modo v, nunca en ambos. Esta página ofrece u y no v, porque un par de botones que se anulan entre sí sin avisar es peor interfaz que uno que es honesto sobre su alcance.

¿Por qué mi regex global se salta una coincidencia de cada dos?+

Porque una regex con el flag g o y tiene estado. Guarda una propiedad lastIndex, y tanto exec como test empiezan desde ahí y la actualizan cuando tienen éxito. Guarda una en una constante a nivel de módulo, llama a test dos veces sobre la misma cadena y la segunda llamada empieza a mitad de camino y devuelve false. El mismo error aparece cuando una regex global se reutiliza entre los elementos de un bucle. Hay tres salidas: crear la regex de nuevo donde se usa, restablecer lastIndex a 0 antes de cada llamada, o usar matchAll y String.match, que no dejan el cursor donde puedas tropezar con él. Esta página evita el problema por completo compilando una copia de trabajo privada en cada ejecución, así que la regex que estás viendo nunca es la que se modifica.

¿Qué puede hacer PCRE que las regex de JavaScript no pueden?+

Varias cosas, y saber cuáles ahorra mucha depuración confusa cuando copias un patrón de un motor a otro. No hay grupos atómicos: el (?>…) de PCRE se compromete con una coincidencia y se niega a volver atrás dentro de ella, que es el arreglo manual estándar para el backtracking catastrófico, y el único sustituto en JavaScript es un lookahead que envuelve una captura. No hay cuantificadores posesivos (a*+) por la misma razón. No hay recursión (?R) ni llamadas a subrutinas, así que los paréntesis equilibrados quedan fuera de alcance. No hay modificadores en línea: (?i) a mitad del patrón es un error de sintaxis, porque un flag de JavaScript se aplica a toda la regex o a nada. No hay condicionales, ni anclas \A \z \Z, ni clases POSIX como [[:alpha:]], ni modo de comentarios. Lo que JavaScript sí tiene y muchos motores no es el lookbehind de longitud variable.

¿\d significa lo mismo en todas partes?+

No, y la diferencia es una fuente real de errores de seguridad. En JavaScript \d es exactamente [0-9], siempre, con o sin el flag u. En .NET y Python 3, \d coincide por defecto con cualquier carácter que tenga la propiedad Unicode de dígito decimal, lo que incluye los dígitos arábigo-índicos ٠١٢, los dígitos devanagari y los de ancho completo 012. Un validador escrito en Python que acepta ٢٠٢٦ y uno en JavaScript que lo rechaza discreparán sobre la misma entrada, que es precisamente el tipo de desajuste que se explota. La misma precaución se aplica a \w, que aquí es [A-Za-z0-9_] y por tanto no considera "é" un carácter de palabra, y a \b, que se define en función de \w y por eso cae en mitad de "naïve". Si quieres semántica Unicode en JavaScript, tienes que pedirla explícitamente: \p{Nd} con el flag u para los dígitos, \p{L} para las letras.

¿Cuándo debo dejar de usar una expresión regular?+

Cuando lo que buscas puede anidarse. Las expresiones regulares en sentido formal no saben contar, y aunque las referencias inversas llevan al motor de JavaScript más allá de un lenguaje estrictamente regular, sigue sin poder reconocer estructuras equilibradas. Eso descarta HTML, XML, JSON, código fuente y cualquier lenguaje con paréntesis, no porque el patrón sea difícil de escribir sino porque no existe ningún patrón. Usa DOMParser, JSON.parse o un analizador de verdad. Tres señales más sutiles apuntan en la misma dirección: el patrón ha crecido más allá de una o dos líneas y nadie puede leerlo, necesita un comentario para explicar cada cláusula, o sigue acumulando casos especiales para entradas que se suponía que ya cubría. Una expresión regular rinde al máximo cuando busca y valida fragmentos planos y bien formados (una fecha, un color hexadecimal, un prefijo de log), y rinde al mínimo cuando finge ser una gramática.

¿Qué significan $1, $&, $` y $' en un reemplazo?+

Son los patrones de sustitución que String.replace entiende en la cadena de reemplazo. De $1 a $99 insertan el texto de ese grupo de captura numerado, y $<name> hace lo mismo con uno con nombre. $& inserta la coincidencia completa. $` inserta todo lo que hay antes de la coincidencia y $' todo lo que hay después; ambos son sorprendentemente útiles para envolver texto y sorprendentemente fáciles de activar por accidente, ya que una barra invertida no los escapa. $$ inserta un único signo de dólar literal. Dos reglas sorprenden a mucha gente: una referencia a un grupo que no existe se deja en la salida como texto plano en lugar de lanzar un error, y $12 significa el grupo 12 si el patrón tiene doce grupos y el grupo 1 seguido del carácter "2" si no los tiene. Esta página los expande todos en la vista previa y señala cualquier referencia que no haya podido resolver.

Más herramientas especializadas, listas cuando las necesites.

Explora una colección cada vez más amplia para cálculos, documentos, escritura y el trabajo diario.

Ver todas las herramientas