Una expresión regular (o regex) es una secuencia de caracteres que podemos usar para apuntar a ciertos elementos de los strings y manipularlos. Así, podemos:
Este concepto se centra en el uso de expresiones regulares en JavaScript. Si quieres aprender a escribir expresiones regulares, Eloquent JavaScript puede ser un buen recurso.
💡 El sabor de regex de JavaScript es parte del estándar ECMA-262 del lenguaje. Esto significa que no tienes que preocuparte por la compatibilidad específica de cada navegador.
En JavaScript, las expresiones regulares se escriben casi siempre en el formato /pattern/modifiers, donde «pattern» es la expresión regular principal y «modifiers» es una serie de caracteres que podemos agregar para indicar opciones especiales (como superpoderes).
Sin embargo, tenemos dos formas de crear una expresión regular:
const regex = /[a-z]/;
const regex = new RegExp('[a-z]');
En ambos casos, JavaScript crea un objeto a partir de la regex. Se recomienda usar patrones inmutables con el literal de forma predeterminada.
El constructor RegExp se puede usar en los casos en los que la regex cambiará o todavía no la conocemos (como un dato que ingresa el usuario).
Las expresiones regulares tienen superpoderes opcionales llamados flags que permiten funcionalidades adicionales. Estas banderas se pueden usar por separado o juntas en cualquier orden, y forman parte de la expresión regular.
Algunas de las más usadas son:
/g - Búsqueda global/i - Sin distinción de mayúsculas y minúsculas/m - Búsqueda multilíneaAquí hay un ejemplo simple:
const re = /home/gi;
const str = 'Home, sweet home.';
str.match(re);
// => ["Home", "home"]
El carácter g nos permite analizar todas las coincidencias posibles dentro de un string. Sin esta funcionalidad, JavaScript solo habría extraído la primera coincidencia de Home.
La bandera /i (sin distinción de mayúsculas y minúsculas) nos permite ser flexibles a la hora de encontrar un patrón. De esta forma, no importa si lo que buscamos está en UPPERCASE o en lowercase.
Cuando usas el constructor RegExp, la sintaxis para agregar banderas es diferente. En este caso, solo necesitas pasar las banderas como segundo argumento.
Cuando las expresiones regulares se combinan con las funciones integradas de JavaScript, tenemos formas muy potentes de manipular y obtener datos de los strings.
El método test() es una gran forma de buscar y saber si un valor objetivo existe dentro de un string dado. De esta manera, devuelve un valor booleano, true o false.
El método match() extrae la coincidencia de la expresión regular de un string dado. Devuelve un array con información y coincidencias.
¿Cuándo usar uno u otro? Usa test() cuando quieras una forma rápida de comprobar un valor dentro de un string, y usa match() si necesitas usar ese valor o quieres más información sobre la coincidencia.
El método test() ejecuta una búsqueda de una coincidencia entre una expresión regular y un string especificado. Devuelve true o false.
const str = 'It is difficult to test if you have a virus';
const result = /virus$/.test(str);
console.log(result);
// => true
Bien, pero ¿y si queremos obtener los valores reales de la búsqueda de la expresión regular?
En lugar de devolver solo un booleano, con el método match() obtenemos un array útil cuyo contenido depende de la presencia o ausencia de las coincidencias encontradas.
De esta forma, podemos tanto buscar como extraer información de cualquier string. Por ejemplo:
const funnyQuote =
'If you see someone crying, ask if it is because of their haircut.';
const regex1 = /someone/;
const regex2 = /happy/;
funnyQuote.match(regex1);
// => ["someone", index: 3, input: "If you see someone crying, ask if it is because of their haircut.", groups: undefined]
funnyQuote.match(regex2);
// => null
Cuando la bandera de búsqueda global /g está presente, en lugar de obtener solo la coincidencia junto con información útil como el índice o la entrada, el método devuelve todas las apariciones presentes en el array:
const funnyQuote =
'If you see someone crying, ask if it is because of their haircut.';
const regex3 = /if/gi;
funnyQuote.match(regex3);
// => ["If", "if"];
El método replace() en JavaScript nos permite buscar un valor dentro de un string dado y reemplazarlo por un valor nuevo.
string.replace(searchValue, newValue);
El patrón para buscar la sustitución puede ser un solo string o una expresión regular.
let string = 'I like dogs!';
let result = string.replace('dogs', 'cats');
let string = 'I would love to travel to Japan';
let result = string.replace(/Japan/g, 'Hawaii');
Además, podemos aplicar una función en la posición de reemplazo para hacer cambios adicionales en cada valor.
let text = 'Say hello to the chatbot.';
let result = text.replace(/chatbot|hello/gi, function (word) {
return word.toUpperCase();
});
// => "Say HELLO to the CHATBOT"
💡 Al final, la combinación de expresiones regulares y el método
replace()es una forma más dinámica de reemplazar elementos. Usar un solo string puede ser limitado.
El método split() en JavaScript representa una forma diferente de usar y manipular strings con expresiones regulares.
De esta forma, usaremos regex para dividir un string dado reconociendo un patrón, por ejemplo str.split(/[,.\s]/). Este patrón se usará como el separator.
const str = 'hello,user.how are.you';
const result = str.split(/[,.\s]/);
console.log(result);
// => ['hello', 'user', 'how', 'are', 'you']
En cuanto al rendimiento, ambos crean un objeto RegExp. La principal diferencia es la frecuencia con la que se compila la regex:
Regular Expression Literal: una vez durante el análisis y la compilación iniciales del códigoRegExp(): cada vez que se crea un objeto nuevo.Usar la sintaxis literal puede ser una mejor opción, no solo por el rendimiento, sino también por simplicidad y legibilidad. Para más detalles, consulta esta discusión en Stack Overflow.
RegExp(), también necesitas escapar las comillas y escapar dos veces las barras invertidas. Eso hace que las expresiones regulares, que ya son difíciles de leer y entender por naturaleza, lo sean aún más.