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 manière similaire à match(), mais renvoie un itérateur avec toutes les correspondances d'expression régulière dans une expression régulière globale ou persistante. Cela offre un moyen simple d'itérer sur les correspondances, en particulier lorsque vous avez besoin d'accéder aux groupes de capture.

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. Prenons l'exemple de code suivant:

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

Exécutez-le dans une console et notez qu'il renvoie un tableau contenant les chaînes 'test1' et 'test2'. Si je supprime l'indicateur g de l'expression régulière, je reçois tous mes groupes de capture, mais je n'obtiens que la première correspondance. Elle 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. Voici la question: comment obtenir tous les groupes de capture pour chaque correspondance ? La présentation de la proposition String.prototype.matchAll() montre deux approches possibles. Je ne vais pas les décrire, car vous n'en aurez peut-être plus besoin très longtemps.

String.prototype.matchAll()

À quoi ressembleraient les exemples d'explication 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 à ce sujet. 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 éléments supplémentaires. 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 format exactement identique à celui renvoyé par match() pour les expressions régulières non globales.

Contenu bonus

Il s'agit principalement d'un guide destiné aux personnes qui débutent avec les expressions régulières ou qui ne sont pas des experts en la matière. Vous avez peut-être remarqué que les résultats de match() et de 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 lacunes dans la documentation sur MDN (que j'ai corrigées). Voici une brève description.

index
Indice du premier résultat dans la chaîne d'origine. Dans l'exemple ci-dessus, test2 commence à la position 5. index a donc la valeur 5.
input
Chaîne complète sur laquelle matchAll() a été exécuté. Dans mon exemple, il s'agissait de 'test1test2'.
groups
Contient les résultats de tous les 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 à me le signaler dans les commentaires ci-dessous. Pour en savoir plus sur les modifications récentes apportées à JavaScript, consultez les mises à jour précédentes ou le site Web V8.