Améliorer la correspondance des résultats avec String.prototype.matchAll()

Joe Medley
Joe Medley

Chrome 73 introduit la méthode String.prototype.matchAll(). Il se comporte de la même manière que match(), mais renvoie un itérateur avec toutes les correspondances d'expression régulière dans une expression régulière globale ou persistante. Il s'agit d'un moyen simple d'itérer des correspondances, en particulier lorsque vous avez besoin d'un accès pour capturer des groupes.

Quel est le problème avec match() ?

La réponse courte est rien, sauf si vous essayez de renvoyer des correspondances globales avec des groupes de capture. Voici un casse-tête de programmation pour vous. Prenons l'exemple du code suivant:

const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const results = string.match(regex);
console.log(results);
// → ['test1', 'test2']

Exécutez la commande dans une console. Notez qu'elle renvoie un tableau contenant les chaînes 'test1' et 'test2'. Si je supprime l'option g de l'expression régulière, ce que je reçois contient tous mes groupes de capture, mais je n'obtiens que la première correspondance. Il se présente comme suit :

['test1', 'e', 'st1', '2', index: 0, input: 'test1test2', groups: undefined]

Cette chaîne contient une deuxième correspondance possible commençant par 'test2', mais je ne l'ai pas. Comment faire pour rassembler tous les groupes de capture pour chaque match ? L'explication de la proposition String.prototype.matchAll() présente deux approches possibles. Je ne les décrirai pas car j’espère que vous n’en aurez pas besoin beaucoup plus.

String.prototype.matchAll()

À quoi ressembleraient les exemples explicatifs avec matchAll() ? Ce fichier KML vous permettra de le savoir.

const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const matches = string.matchAll(regex);
for (const match of matches) {
  console.log(match);
}

Voici quelques points à noter. Contrairement à match(), qui renvoie un tableau lors d'une recherche globale, matchAll() renvoie un itérateur qui fonctionne parfaitement avec les boucles for...of. L'itérateur produit un tableau pour chaque correspondance, y compris les groupes de capture avec quelques extras. Si vous les imprimez dans la console, elles se présentent comme suit:

['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', groups: undefined]
['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', groups: undefined]

Vous remarquerez peut-être que la valeur de chaque correspondance est un tableau au même format que celui renvoyé par match() pour les expressions régulières non globales.

Contenu supplémentaire

Elle s'adresse principalement aux personnes qui débutent avec les expressions régulières ou qui ne sont pas expertes en la matière. Vous avez peut-être remarqué que les résultats de match() et matchAll() (pour chaque itération) sont des tableaux avec des propriétés nommées supplémentaires. Lors de la préparation de cet article, j'ai remarqué que ces propriétés présentaient des défauts de documentation sur MDN (que j'ai corrigés). En voici une brève description.

index
Index du premier résultat de la chaîne d'origine. Dans l'exemple ci-dessus, test2 commence à la position 5, et index a donc la valeur 5.
input
Chaîne complète sur laquelle matchAll() a été exécuté. Dans mon exemple, il s'agit de 'test1test2'.
groups
Contient les résultats des groupes de capture nommés spécifiés dans votre expression régulière.

Conclusion

Si j'ai oublié quelque chose, n'hésitez pas à nous en faire part dans les commentaires ci-dessous. Pour en savoir plus sur les récentes modifications apportées à JavaScript dans les mises à jour précédentes, consultez le site Web de la version 8.