Chrome 73 presenta el método String.prototype.matchAll()
. Se comporta de manera similar a match()
, pero muestra un iterador con todas las coincidencias de expresión regular en una expresión regular global o fija. Esto ofrece una forma simple de
iterar sobre las coincidencias, especialmente cuando necesitas acceso a los grupos de captura.
¿Qué problema tiene match()?
La respuesta corta es nada, a menos que intentes mostrar coincidencias globales con grupos de captura. Aquí tienes un acertijo de programación. Considera el siguiente código:
const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const results = string.match(regex);
console.log(results);
// → ['test1', 'test2']
Ejecuta esto en una consola y observa que muestra un array que contiene las cadenas 'test1'
y 'test2'
. Si quito la marca g de la expresión regular, lo que obtengo tiene todos mis grupos de captura, pero solo obtengo la primera coincidencia. El aspecto resultante será el siguiente:
['test1', 'e', 'st1', '2', index: 0, input: 'test1test2', groups: undefined]
Esta cadena contiene una segunda coincidencia posible que comienza con 'test2'
, pero no la tengo. Ahora, el enigma es el siguiente: ¿cómo obtengo todos los grupos de captura para cada coincidencia? En la explicación de la propuesta de String.prototype.matchAll(), se muestran dos enfoques posibles. No los describiré porque, con suerte, no los necesitarás por mucho tiempo.
String.prototype.matchAll()
¿Cómo se verían los ejemplos de la explicación con matchAll()
? ¡Descúbrelo!
const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const matches = string.matchAll(regex);
for (const match of matches) {
console.log(match);
}
Hay algunos aspectos que debes tener en cuenta. A diferencia de match()
, que muestra un array en una búsqueda global, matchAll()
muestra un iterador que funciona de forma excelente con los bucles for...of
. El iterador produce un array para cada coincidencia, incluidos los grupos de captura con algunos elementos adicionales. Si los imprimes en la consola, se verán de la siguiente manera:
['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', groups: undefined]
['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', groups: undefined]
Es posible que notes que el valor de cada coincidencia es un array en el mismo formato que muestra match()
para las expresiones regulares no globales.
Material adicional
Esto es principalmente para personas que son nuevas en el uso de expresiones regulares o que no son expertas en ellas. Es posible que hayas notado que los resultados de match() y matchAll() (para cada iteración) son arrays con algunas propiedades nombradas adicionales. Mientras preparaba este artículo, noté que estas propiedades tienen algunas deficiencias de documentación en MDN (que corregí). Aquí tienes una descripción breve.
index
- Es el índice del primer resultado en la cadena original. En el ejemplo anterior,
test2
comienza en la posición 5, por lo queindex
tiene el valor 5. input
- Es la cadena completa con la que se ejecutó
matchAll()
. En mi ejemplo, era'test1test2'
. groups
- Contiene los resultados de cualquier grupo de captura con nombre especificado en tu expresión regular.
Conclusión
Si me faltó algo, avísame en los comentarios a continuación. Puedes obtener más información sobre los cambios recientes en JavaScript en actualizaciones anteriores o en el sitio web de V8.