MiServe DevTools

Tus pegatinas

Fija aquí tus herramientas. Se guardan en este navegador.

Tester de regex para JavaScript y Go (RE2)

Prueba una expresión regular sobre tu texto con el motor de JavaScript o con el motor RE2 de Go, y ve cada coincidencia, cada grupo de captura y el reemplazo.

Flags

Coincidencias en el texto

Referencia rápida de sintaxis de los dos motores
TokenSignificadoJavaScriptGo (RE2)
. Cualquier carácter excepto un salto de línea. Con el flag s también incluye los saltos de línea. Sí Sí
\d \w \s Un dígito, un carácter de palabra, un carácter de espacio en blanco. Las mayúsculas \D, \W y \S significan lo contrario. Sí Sí
[abc] [^abc] [a-z] Un carácter de un conjunto, un carácter que no está en el conjunto, un carácter dentro de un rango. Sí Sí
^ $ Inicio y fin del texto. Con el flag m, inicio y fin de cada línea. Sí Sí
\b \B Un límite de palabra, y una posición que no es límite de palabra. Sí Sí
* + ? {2,5} Cero o más veces, una o más, cero o una, entre 2 y 5 veces. Cada uno toma todo lo que puede. Sí Sí
*? +? ?? {2,5}? Los mismos cuantificadores, tomando lo mínimo posible. Sí Sí
(…) (?:…) Un grupo de captura, y un grupo que solo agrupa. Sí Sí
(?<name>…) Un grupo de captura con nombre. Go acepta esta forma desde la versión 1.22, y (?P<name>…) en todas las versiones. Sí Sí
a|b a o b. Sí Sí
\p{L} \p{Lu} Una propiedad Unicode: cualquier letra, cualquier letra mayúscula. En JavaScript necesita el flag u. Sí Sí
(?i) (?s) (?m) Flags escritos dentro del patrón. En JavaScript, los flags se indican fuera de él. No Sí
\A \z Inicio y fin del texto completo, diga lo que diga el flag m. No Sí
[[:alpha:]] Una clase de caracteres POSIX dentro de un conjunto. No Sí
(?=…) (?!…) Lookahead: lo que sigue debe coincidir, o no debe coincidir, sin consumirlo. Sí No
(?<=…) (?<!…) Lookbehind: lo que precede debe coincidir, o no debe coincidir. Sí No
\1 \k<name> Referencia inversa (backreference): el mismo texto que capturó un grupo anterior. Sí No

Funciona en tu navegador con WebAssembly. Nada de lo que pegas se sube.

Acerca de esta herramienta

Dos motores de dos familias

Los motores de expresiones regulares se dividen en dos familias. Los motores con backtracking, como PCRE y los motores predeterminados de JavaScript, Python, Java y .NET, prueban un camino a través del patrón y retroceden cuando falla. Ese diseño es lo que hace posibles el lookahead, el lookbehind y las referencias inversas. Los motores basados en autómatas, como RE2 y el paquete regexp de Go, siguen a la vez todos los caminos posibles, así que su tiempo de ejecución crece de forma lineal con la longitud del texto. El precio es que no tienen lookaround ni referencias inversas.

Aquí, el motor de JavaScript es el propio RegExp de tu navegador. El motor de Go es el paquete estándar regexp de Go compilado a WebAssembly, así que el código que ejecuta aquí tu patrón es el mismo que lo ejecuta en un programa en Go. Go acepta la sintaxis de RE2.

Cómo leer los resultados

Cada coincidencia se enmarca y se resalta en el texto con dos colores alternos, para distinguir las coincidencias que se tocan. Una coincidencia vacía, como la que x* encuentra entre dos letras, se dibuja como una barra fina. La tabla muestra el inicio y el fin de cada coincidencia y el texto de cada grupo de captura. Un grupo que no participó en una coincidencia se marca como sin coincidencia, que no es lo mismo que un grupo que coincidió con una cadena vacía.

Las posiciones cuentan unidades de código UTF-16 empezando por cero, y el fin es exclusivo: son los números que pasarías a String.prototype.slice en JavaScript. Go, por su parte, devuelve desplazamientos en bytes sobre texto UTF-8; la herramienta los convierte, así que los dos motores muestran los mismos números.

En JavaScript, un patrón sin el flag g encuentra solo la primera coincidencia y reemplaza solo la primera coincidencia. El motor de Go siempre devuelve todas las coincidencias, como hacen FindAllStringSubmatchIndex y ReplaceAllString.

Backtracking catastrófico

Un motor con backtracking puede necesitar un tiempo exponencial cuando los cuantificadores están anidados o se solapan. El caso clásico es (a+)+$ probado contra una larga secuencia de a seguida de otro carácter: el motor prueba todas las formas de repartir la secuencia entre el cuantificador interior y el exterior antes de rendirse. En un servidor esto es un riesgo de denegación de servicio conocido como ReDoS.

Esta herramienta ejecuta los patrones de JavaScript en un worker en segundo plano y lo detiene a los 1,5 segundos, para que la página siga respondiendo y te diga qué ha pasado. Probar el mismo patrón con el motor de Go es una forma rápida de ver si la lentitud viene del backtracking, porque Go garantiza un tiempo de ejecución lineal respecto a la longitud del texto.

Preguntas

¿Por qué mi patrón funciona en JavaScript pero falla en Go?

Una causa habitual es el lookahead, el lookbehind o una referencia inversa, que RE2 deja fuera para poder garantizar un tiempo de ejecución lineal. Los flags son otra causa frecuente: Go no tiene flags fuera del patrón, así que la búsqueda sin distinguir mayúsculas y minúsculas se escribe como (?i) al principio del patrón.

¿En qué se diferencian las cadenas de reemplazo de JavaScript y de Go?

Las dos usan $1 para el primer grupo. Un grupo con nombre es $<name> en JavaScript y ${name} en Go. En Go, $1x significa un grupo llamado 1x, así que escribe ${1}x cuando a la referencia le sigue una letra, un dígito o un guion bajo.

¿Puedo probar aquí patrones de PCRE, Python o Java?

En esta página solo se ejecutan los motores de JavaScript y Go. La sintaxis de uso diario es común a los distintos dialectos, así que el motor de JavaScript es una buena aproximación para patrones sencillos, pero funciones como los cuantificadores posesivos, los grupos atómicos y la recursión no están disponibles en ninguno de los dos motores.

¿Se envía a un servidor el texto que pruebo?

No. Los dos motores funcionan en tu navegador: JavaScript en un worker en segundo plano y Go como módulo WebAssembly. La herramienta no hace ninguna petición de red con tu patrón ni con tu texto, y la política de seguridad del sitio bloquea las peticiones a cualquier otro host.

Más herramientas de Texto