Buscar y reemplazar

Búsqueda y/o reemplazo de fragmentos de textos


Una operación muy frecuente y habitual en Javascript, es la de comprobar la existencia de un texto, buscar o incluso reemplazar por otro texto. Dependiendo del caso, hará falta uno u otro, por lo que lo primero que debes tener claro es saber cuál necesitas. Piensa que, aunque la sintaxis o el uso de uno de ellos te resulte más sencillo que otro, hay tareas que puede que no necesites realizar gratuitamente:

  • 🔍 Comprobación (🔍): La más ligera de las tres. Sólo comprueba si existe el fragmento de texto.
  • 🕵️‍♀️ Búsqueda (🔍+🕵️‍♀️): Busca un fragmento de texto y devuelve encontrado (posición, texto...).
  • 🔁 Reemplazo (🔍+🕵️‍♀️+🔁): Realiza una búsqueda de un texto y además un reemplazo. Suele ser más costoso.

Comprobación en textos

Los siguientes métodos se utilizan para realizar algún tipo de comprobación y saber si un fragmento de texto está incluído en un :

MétodoDescripción
.startsWith(text, from) Comprueba si el texto comienza por text.
.endsWith(text, to) Comprueba si el texto termina por text.
.includes(text, from) Comprueba si el texto contiene el subtexto text.

Observa que en cada método tienes un segundo parámetro opcional, donde se puede indicar desde donde quieres empezar a comprobar (en el caso de from), o hasta donde quieres comprobar (en el caso de to).

  • El método .startsWith() devolverá true si el comienza por text. De lo contrario, false.
  • El método .endsWith() devolverá true si el acaba en text. De lo contrario, false.
  • El método .includes() devolverá true si el contiene text. De lo contrario, false.

Veamos algunos ejemplos:

const text = "Manz";

text.startsWith("M");     // true  ('Manz' empieza por 'M')
text.startsWith("a", 1);  // true  ('anz' empieza por 'a')
text.endsWith("o");       // false ('Manz' no acaba en 'o')
text.endsWith("n", 3);    // true  ('Man' acaba en 'n')
text.includes("an");      // true  ('Manz' incluye 'an')
text.includes("M", 1);    // false ('anz' no incluye 'M')

Ten en cuenta que los del segundo parámetro, lo que hacen es acortar el (por el inicio o por el final) antes de realizar la comprobación.

Búsqueda de cadenas de textos

Si necesitamos realizar una búsqueda de un texto (que muchas veces no tenemos claro como es) y queremos obtener información como la posición o las búsquedas encontradas, y los métodos del tema anterior de posiciones y substrings no nos sirven (o se nos quedan cortos), podemos utilizar alguno de los siguientes:

MétodoDescripción
.search(regexp)Busca un patrón que encaje con regexp y devuelve la posición encontrada.
.match(regexp)Idem a la anterior, pero devuelve las coincidencias encontradas.
.matchAll(regexp) Idem a la anterior, pero devuelve un iterador para iterar por cada coincidencia.

Estas búsquedas toman por parámetro expresiones regulares, por lo que suelen ser más potentes y flexibles que buscar sólo por texto. La diferencia fundamental entre ellas es la siguiente:

  • El método .search() devuelve la posición de la primera ocurrencia. -1 si no se encuentra.
  • El método .match() devuelve un con las coincidencias encontradas. null si no se encuentran.
  • El método .matchAll() devuelve un iterador para poder recorrer las coincidencias encontradas.

Veamos algunos ejemplos:

const text = "El gato, el perro y el pato.";
const regexp = /.a.o/g;

text.search(regexp);   // 3, porque la primera coincidencia ocurre en la posición 3 (gato)
text.match(regexp);    // ["gato", "pato"], las dos coincidencias encontradas

Por otro lado, el método .matchAll() es un poco más avanzado, y permite realizar la misma acción que .match() pero devolviendo un iterador, lo que nos permite recorrerlo en un bucle:

const text = "El gato, el perro y el pato.";
const regexp = /.a.o/g;

const iterator = text.matchAll(regexp);
for (let ocurrence of iterator) {
  console.log(ocurrence);
}

// ['gato', index: 3, input: 'El gato, el perro y el pato.', groups: undefined]
// ['pato', index: 23, input: 'El gato, el perro y el pato.', groups: undefined]

También es posible utilizar .matchAll() desestructurando su resultado, lo que nos permitirá acceder a la información de una forma más directa:

const text = "El gato, el perro y el pato.";
const regexp = /.a.o/g;
const results = [...text.matchAll(regexp)];    // ["gato", "pato"]

results.length     // 2
results[0].index   // 3
results[1].index   // 23

Para comprender bien el funcionamiento de este método, quizás sería mejor echar un vistazo al tema de Arrays y de Expresiones regulares, que se aborda unos capítulos más adelante.

Reemplazar cadenas de texto

Si lo que necesitamos es reemplazar un texto, tenemos a nuestra disposición una serie de métodos, tanto en versión donde buscas mediante un , como en versión donde buscas mediante una :

MétodoDescripción
.replace(text, newText)Reemplaza la primera aparición del text por newText.
.replace(regexp, newText)Idem, pero busca a partir de una en lugar de un .
.replaceAll(text, newText) Reemplaza todas las apariciones del texto text por newText.
.replaceAll(regexp, newText) Idem, pero busca a partir de una en lugar de un .

Observa que dichos métodos se pueden resumir en lo siguiente:

  • El método replace() reemplaza solo la primera aparición de un texto (salvo se use regexp global)
  • El método replaceAll() reemplaza todas las apariciones de un texto.
  • El método replace() con Regexp permite reemplazar todas las apariciones con algunos extras.

Veamos algunos ejemplos para ilustrarlo mejor.

La función replace()

En este caso, veamos que usaremos el método .replace(), que permite reemplazar sólo la primera coincidencia de la búsqueda:

const text = "Hola gato, ¿eres un perro o eres un pato?";

// *** Reemplazar la primera ocurrencia

// Cambia la primera "a" por una "i"
text.replace("a", "i");       // "Holi gato, ¿eres un perro o eres un pato?"

// Cambia la primera "g" por una "p"
text.replace("g", "p");       // "Hola pato, ¿eres un perro o eres un pato?"

// Dos acciones. Cambia la primera "g" por una "p" y la primera "o" por una "a"
text.replace("g", "p")
    .replace("o", "a");       // "Hala pato, ¿eres un perro o eres un pato?"

Ten en cuenta que text no cambia (no muta), es decir, el método .replace() devuelve un nuevo con el texto original reemplazado. En los ejemplos anteriores, cada linea está actuando sobre la constante text de la primera línea.

El primer grupo, reemplaza sólo la primera ocurrencia encontrada. Observa que el tercer ejemplo encadena varios .replace() consecutivos, por lo que se reemplaza la primera ocurrencia de g por p y del resultado, se reemplaza la primera ocurrencia de o por a.

La función replaceAll()

A diferencia de la anterior función replace(), mediante la función replaceAll(), podemos reemplazar todos los textos coincidentes y no sólo la primera ocurrencia:

// *** Reemplazar todas las ocurrencias

text.replaceAll("e", "i");    // "Hola gato, ¿iris un pirro o iris un pato?"

Como puedes ver, en este ejemplo, se reemplazan todas las "e" por "i".

Además, con replace() podemos indicar expresiones regulares en lugar de , por lo que podemos emular el funcionamiento de un replaceAll() o incluso realizar reemplazos mucho más potentes y flexibles mediante las características de las expresiones regulares.

El siguiente ejemplo realiza el mismo reemplazo del ejemplo anterior con replaceAll() pero utilizando solamente replace() y una expresión regular muy sencilla:

text.replace(/e/g, "i");      // "Hola gato, ¿iris un pirro o iris un pato?"

La función replace() con RegExp

Como hemos mencionado, la forma más potente de reemplazar todas las ocurrencias y ciertos añadidos muy potentes y flexibles, es utilizando .replace() con una expresión regular global. Las expresiones regulares permiten crear patrones complejos que coicindan en múltiples casos.

Por ejemplo, el siguiente caso reemplaza todas las letras vocales por una letra i:

const daenerys = "Javascript es un gran lenguaje";

daenerys.replace(/[aeou]/g, "i");     // 'Jiviscript is in grin lingiiji'

Recuerda que Javascript ha incorporado ya una función replaceAll() para reemplazar todas las ocurrencias de un texto sin necesidad de usar una expresión regular.

Función para reemplazar

Además, tanto el método .replace() como el método .replaceAll(), nos permite indicar, como segundo parámetro una en lugar de un , permitiendo utilizar dicha función para realizar un reemplazo. En lugar de simplemente reemplazar por un , se reemplaza por lo que devuelve dicha .

Observa ahora, la versión del .replace() donde le pasamos un segundo parámetro que es una que reemplaza el texto encontrado:

const text = "Hola gato, ¿eres un perro o eres un pato?";
const replaceAction = (value) => `=>${value}<=`;

text.replace(/.ato/g, replaceAction);
// "Hola =>gato<=, ¿eres un perro o eres un =>pato<=?"

text.replaceAll("un", replaceAction);
// "Hola gato, ¿eres =>un<= perro o eres =>un<= pato?"

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev