Las expresiones regulares buscan patrones dentro de un texto: validar un correo, extraer fechas, limpiar espacios. En JavaScript se escriben entre barras, /patrón/banderas, y se usan con métodos de las cadenas.
También te puede interesar
Comprobar si un texto encaja
const correo = /^[^\s@]+@[^\s@]+\.[a-z]{2,}$/i;
for (const c of ["ana@ejemplo.com", "ANA@EJEMPLO.MX", "ana@ejemplo", "ana @ejemplo.com"]) {
console.log(c.padEnd(18), correo.test(c));
}salidaana@ejemplo.com true ANA@EJEMPLO.MX true ana@ejemplo false ana @ejemplo.com false
test devuelve true o false. Los anclajes ^ y $ obligan a que encaje el texto entero y no solo un trozo, y la bandera i ignora mayúsculas. Esta expresión es deliberadamente sencilla: comprueba la forma de un correo, no que exista.
Extraer partes: grupos con nombre
const texto = "Pedido 1042 del 2026-10-19, pedido 1043 del 2026-10-21.";
const fecha = /(?<anio>\d{4})-(?<mes>\d{2})-(?<dia>\d{2})/;
const m = texto.match(fecha);
console.log(m[0], "|", m.groups.dia, m.groups.mes, m.groups.anio, "| en la posición", m.index);
console.log(texto.match(/\d{4}-\d{2}-\d{2}/g));
for (const { groups, index } of texto.matchAll(/pedido (?<num>\d+)/gi)) {
console.log(`pedido ${groups.num} en la posición ${index}`);
}
console.log(texto.replace(/(?<a>\d{4})-(?<m>\d{2})-(?<d>\d{2})/g, "$<d>/$<m>/$<a>"));salida2026-10-19 | 19 10 2026 | en la posición 16 [ '2026-10-19', '2026-10-21' ] pedido 1042 en la posición 0 pedido 1043 en la posición 28 Pedido 1042 del 19/10/2026, pedido 1043 del 21/10/2026.
(?<nombre>...) captura un trozo de la coincidencia y lo deja en groups. Esquema: decodigo.com.Tres formas de buscar, según lo que quieras:
| Método | Qué devuelve |
|---|---|
texto.match(/.../) | La primera coincidencia, con sus grupos e index |
texto.match(/.../g) | Solo los textos de todas las coincidencias, sin grupos |
texto.matchAll(/.../g) | Todas las coincidencias, cada una con grupos e index |
Y en replace, $<nombre> se sustituye por lo que capturó ese grupo: así se reordena una fecha en una línea.
Reemplazar con una función, y otros usos
const precios = "Teclado 49.9, ratón 19.5, monitor 189";
const conIva = precios.replace(/\d+(\.\d+)?/g, (n) => (Number(n) * 1.16).toFixed(2));
console.log(conIva);
console.log("a-b_c d".split(/[-_ ]/));
console.log(" muchos espacios aquí ".trim().replace(/\s+/g, " "));
console.log("1.5".replace(".", ","), "|", "1.5.0".replaceAll(".", ","));
console.log("x.y.z".replace(/./g, "*"));salidaTeclado 57.88, ratón 22.62, monitor 219.24 [ 'a', 'b', 'c', 'd' ] muchos espacios aquí 1,5 | 1,5,0 *****
Si el segundo argumento de replace es una función, se llama con cada coincidencia y lo que devuelva la sustituye. Las dos últimas líneas muestran dos detalles: replace con una cadena cambia solo la primera aparición (para todas está replaceAll), y en una expresión el punto significa «cualquier carácter»: por eso /./g lo tapa todo.
Acentos y eñes: la bandera u
const palabra = /^\w+$/;
console.log(palabra.test("cafe"), palabra.test("café"), palabra.test("año"));
const letras = /^\p{L}+$/u;
console.log(letras.test("cafe"), letras.test("café"), letras.test("año"));salidatrue false false true true true
\w solo reconoce letras inglesas: ni «é» ni «ñ» son para él caracteres de palabra. Con la bandera u se pueden usar categorías de Unicode, y \p{L} significa «cualquier letra de cualquier idioma». Para textos en español, es la que conviene.
La trampa de lastIndex
const esNumero = /\d+/g;
console.log(esNumero.test("abc 123"), esNumero.lastIndex);
console.log(esNumero.test("abc 123"), esNumero.lastIndex);
console.log(esNumero.test("abc 123"), esNumero.lastIndex);salidatrue 7 false 0 true 7
El mismo test sobre el mismo texto da true, luego false, y luego otra vez true. Con la bandera g, la expresión recuerda en lastIndex dónde se quedó y la siguiente búsqueda empieza ahí. Regla práctica: no uses g con test; solo hace falta para buscar todas las coincidencias.
Buscar un texto literal: RegExp.escape
Si construyes una expresión a partir de lo que escribe el usuario, sus paréntesis, puntos y signos + se interpretan como parte del patrón. Un paréntesis sin cerrar ni siquiera compila:
new RegExp("precio (USD")SyntaxError: Invalid regular expression: /precio (USD/: Unterminated groupRegExp.escape, recién llegado al lenguaje y ya disponible en Node 24, escapa todo lo necesario:
const buscado = "1+1 (suma)";
const exacto = new RegExp(RegExp.escape(buscado));
console.log(exacto.source);
console.log(exacto.test("¿Cuánto es 1+1 (suma)?"));
console.log(new RegExp(buscado).test("¿Cuánto es 1+1 (suma)?"));salida\x31\+1\x20\(suma\) true false
La primera línea parece rara pero es correcta: también escapa el primer dígito y los espacios, como \x31 y \x20, para que el resultado sea seguro en cualquier posición del patrón. La última línea muestra lo que pasa sin escapar: el + y los paréntesis cambian el significado y la búsqueda falla.
RegExp.escape no existe. Si tu código tiene que funcionar en ellos, la alternativa clásica es texto.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), que escapa los caracteres especiales uno a uno.Todo el código de esta página se ejecutó con Node.js 24.22 en un contenedor limpio antes de publicarla; las salidas, incluidos los errores, están copiadas de esa ejecución. Documentación oficial: la guía de expresiones regulares de MDN.