Para probar expresiones regulares en línea, escribe un patrón de JavaScript y un texto de prueba, y la herramienta resalta las coincidencias, muestra la posición y los grupos de cada una, prueba el reemplazo y te explica el patrón pieza por pieza. Si el patrón tiene un error, te dice en español qué falla. Todo se ejecuta en tu navegador: ni el patrón ni el texto se envían a ningún sitio.
Usa el motor de expresiones regulares de tu navegador, el mismo de JavaScript y Node.js. Si el patrón es para Python, Java, Go o PHP, la mayoría de la sintaxis es igual, pero hay diferencias: más abajo están las de Python. Para que un patrón lento no bloquee la página, la búsqueda se hace aparte y se detiene si tarda más de un segundo.
Chuleta rápida
- Caracteres:
.cualquiera salvo el salto de línea;\ddígito;\wletra sin acento, dígito o_;\sespacio en blanco; en mayúsculas, lo contrario (\D,\W,\S). Con la banderau,\p{L}es una letra de cualquier idioma, con acentos y eñes. - Clases:
[abc]uno de esos;[a-z]un rango;[^0-9]cualquiera que no esté. - Cuantificadores:
*cero o más;+uno o más;?opcional;{3}exactamente 3;{2,5}de 2 a 5. Con un?detrás (+?,*?) toman lo mínimo posible. - Anclas:
^principio y$final del texto (o de cada línea conm);\blímite de palabra. - Grupos:
(…)captura;(?:…)agrupa sin capturar;(?<nombre>…)captura con nombre;\1o\k<nombre>repiten lo capturado;a|buna cosa u otra. - Comprobaciones:
(?=…)lo que sigue coincide;(?!…)no coincide;(?<=…)lo anterior coincide;(?<!…)no coincide. No consumen texto. - Reemplazo:
$1el grupo 1;$<nombre>el grupo con nombre;$&la coincidencia entera;$$un signo de dólar.
Las banderas
- g (global): busca todas las coincidencias. Sin ella, solo la primera.
- i: no distingue mayúsculas de minúsculas.
- m (multilínea):
^y$marcan el principio y el final de cada línea. - s (dotAll): el punto también coincide con el salto de línea.
- u (Unicode): trata los emojis y otros caracteres fuera del plano básico como uno solo, activa
\p{…}y es más estricta con los escapes. - v (unicodeSets): una versión ampliada de
ucon operaciones entre clases, como[\p{L}--[a-z]]. Está en todos los navegadores desde septiembre de 2023 y no se puede combinar conu. - y (sticky): solo busca en la posición exacta donde terminó la coincidencia anterior.
Patrones lentos: el retroceso catastrófico
El motor de JavaScript, como el de Python o el de Java, prueba alternativas y retrocede cuando una falla. Con cuantificadores anidados, como (a+)+$, un texto que casi coincide, como muchas «a» seguidas de una «b», obliga a probar todas las formas de repartir las «a» entre las repeticiones: el tiempo se duplica con cada letra más. Pulsa el ejemplo Patrón lento para verlo: la búsqueda va en un proceso aparte (un Web Worker), y si pasa de un segundo la herramienta lo detiene. La solución suele ser quitar el anidamiento: a+$ hace lo mismo sin el problema. Go y Rust no tienen este problema porque sus motores no retroceden, a cambio de no admitir comprobaciones como (?=…) ni referencias como \1.
Diferencias con Python
- Grupos con nombre: en Python se escriben
(?P<nombre>…), se repiten con(?P=nombre)y en el reemplazo van como\g<nombre>. En JavaScript son(?<nombre>…),\k<nombre>y$<nombre>. - Lookbehind: en Python, lo que va dentro de
(?<=…)debe tener una longitud fija:(?<=\d+)da error. JavaScript admite cualquier longitud. \d,\wy\s: en Python, con textosstr, son Unicode por defecto:\wincluye la «ñ» y las vocales con acento. En JavaScript son solo ASCII; para letras de cualquier idioma, usa\p{L}con la banderau. En Python,re.ASCIIhace que se comporten como en JavaScript.- El final del texto: en Python,
$sin multilínea también coincide antes de un salto de línea final; para el final exacto se usa\Z(o\zdesde Python 3.14). En JavaScript,$sinmsolo es el final. - Banderas: en Python van como argumento (
re.I,re.M,re.S) o dentro del patrón con(?i)al principio. No hayg: se elige la función,re.searchpara la primera yre.finditerore.findallpara todas. - Coincidencias vacías: después de una coincidencia vacía, JavaScript avanza un carácter;
re.finditervuelve a intentar en la misma posición una coincidencia que no sea vacía. Cona?|bsobreb, JavaScript da dos coincidencias vacías, en las posiciones 0 y 1, y Python da tres: la vacía de la posición 0, la «b» y la vacía del final. - Grupos repetidos que coinciden vacíos: en
(a*)*bsobreb, el grupo 1 queda sin valor en JavaScript y vale una cadena vacía en Python.
Expresiones regulares en Python
El mismo ejemplo de las fechas, con re.finditer y re.sub:
import re
texto = "Entregas: 2026-10-21, 2026-11-05 y 2027-01-15."
# En Python, los grupos con nombre llevan una P: (?P<nombre>...)
fecha = re.compile(r"(?P<anio>\d{4})-(?P<mes>\d{2})-(?P<dia>\d{2})")
for m in fecha.finditer(texto):
print(m.start(), m.end() - 1, m.group(), m.groupdict())
# En el reemplazo, \g<nombre> (en JavaScript sería $<nombre>)
print(fecha.sub(r"\g<dia>/\g<mes>/\g<anio>", texto))
# Banderas: re.IGNORECASE, re.MULTILINE, re.DOTALL; re.ASCII para que \d y \w sean solo ASCII, como en JavaScript
print(re.findall(r"^\w+", "uno\ndós\ntres", re.MULTILINE))
print(re.findall(r"^\w+", "uno\ndós\ntres", re.MULTILINE | re.ASCII))
try:
re.compile(r"(?<=\d+)x") # en Python, el lookbehind debe tener longitud fija
except re.error as e:
print("error:", e)$ python3 regex.py10 19 2026-10-21 {'anio': '2026', 'mes': '10', 'dia': '21'}
22 31 2026-11-05 {'anio': '2026', 'mes': '11', 'dia': '05'}
35 44 2027-01-15 {'anio': '2027', 'mes': '01', 'dia': '15'}
Entregas: 21/10/2026, 05/11/2026 y 15/01/2027.
['uno', 'dós', 'tres']
['uno', 'd', 'tres']
error: look-behind requires fixed-width patternGuías de expresiones regulares en cada lenguaje: JavaScript, Python, Java, Go y Rust. Otras herramientas para desarrolladores, en decodigo.com/herramientas.
Banderas, grupos con nombre, lookbehind y patrones de reemplazo: MDN, RegExp, la bandera v, lookbehind y String.prototype.replace. Python: documentación del módulo re. El recorrido de la herramienta coincide con matchAll del navegador en 5,100 casos (300 patrones), y sus posiciones, con las de Python re (con re.ASCII y el mismo avance tras las coincidencias vacías) en los mismos 5,100 casos.