Cette page a été traduite à partir de l'anglais par la communauté. Vous pouvez contribuer en rejoignant la communauté francophone sur MDN Web Docs.

View in English Always switch to English

String : méthode matchAll()

Baseline
Large disponibilité

Cette fonctionnalité est bien établie et fonctionne sur de nombreux appareils et versions de navigateurs. Elle est disponible sur tous les navigateurs depuis janvier 2020.

La méthode matchAll() des valeurs String retourne un itérateur contenant l'ensemble des résultats correspondant à cette chaîne de caractères par rapport à une expression rationnelle, y compris les groupes capturant.

Exemple interactif

const regexp = /t(e)(st(\d?))/g;
const str = "test1test2";

const array = [...str.matchAll(regexp)];

console.log(array[0]);
// Résultat attendu : Array ["test1", "e", "st1", "1"]

console.log(array[1]);
// Résultat attendu : Array ["test2", "e", "st2", "2"]

Syntaxe

js
matchAll(regexp)

Paramètres

regexp

Un objet représentant une expression rationnelle, ou tout objet possédant une méthode Symbol.matchAll.

Si regexp n'est pas un objet RegExp et ne possède pas de méthode Symbol.matchAll, il est implicitement converti en RegExp en utilisant new RegExp(regexp, 'g').

Si regexp est une expression rationnelle, alors il doit avoir l'indicateur global (g) activé, sinon un TypeError est levé.

Valeur de retour

Un objet itérateur itérable (qui ne peut pas être relancé) contenant les correspondances ou un itérateur vide si aucune correspondance n'est trouvée. Chaque valeur retournée par l'itérateur est un tableau ayant la même structure que la valeur de retour de RegExp.prototype.exec().

Exceptions

TypeError

Levé si le paramètre regexp est une expression rationnelle qui n'a pas l'indicateur global (g) activé (sa propriété flags ne contient pas "g").

Description

L'implémentation de String.prototype.matchAll ne fait pas grand-chose d'autre que d'appeler la méthode Symbol.matchAll de l'argument avec la chaîne de caractères comme premier paramètre (à part la validation supplémentaire que l'expression rationnelle est globale). L'implémentation réelle provient de RegExp.prototype[Symbol.matchAll]().

Exemples

Regexp.prototype.exec() et matchAll()

Sans matchAll(), il est possible d'utiliser l'appel à regexp.exec() (et des expressions rationnelles avec l'indicateur g) dans une boucle pour obtenir toutes les correspondances :

js
const regexp = /foo[a-z]*/g;
const chaine = "table football, foosball";

let correspondance;
while ((correspondance = regexp.exec(chaine)) !== null) {
  console.log(
    `${correspondance[0]} trouvé. Prochaine recherche à partir de ${regexp.lastIndex}.`,
  );
  // dans la console : "foo trouvé. Prochaine recherche à partir de 9."
  // dans la console : "foo trouvé. Prochaine recherche à partir de 19."
}

Avec matchAll(), on peut éviter la boucle while et le marqueur global. On récupère l'itérateur et on utilise une boucle for...of, la décomposition de tableau ou le constructeur Array.from() :

js
const regexp = /foo[a-z]*/g;
const chaine = "table football, foosball";
const correspondances = chaine.matchAll(regexp);

for (const correspondance of correspondances) {
  console.log(
    `${correspondance[0]} trouvé start=${correspondance.index} end=${
      correspondance.index + correspondance[0].length
    }.`,
  );
}
// football trouvé start=6 end=14.
// foosball trouvé start=16 end=24.

// L'itérateur correspondants est épuisé après l'itération for…of
// Appelez à nouveau matchAll pour créer un nouvel itérateur
correspondances = chaine.matchAll(regexp);

Array.from(correspondances, (m) => m[0]);
// [ "football", "foosball" ]

matchAll lève une exception si l'indicateur g est absent.

js
const regexp = /[a-c]/;
const str = "abc";
str.matchAll(regexp);
// TypeError

matchAll crée en interne une copie de regexp — ainsi, contrairement à regexp.exec(), lastIndex ne change pas pendant le parcours de la chaîne de caractères.

js
const regexp = /[a-c]/g;
regexp.lastIndex = 1;
const str = "abc";
Array.from(str.matchAll(regexp), (m) => `${regexp.lastIndex} ${m[0]}`);
// [ "1 b", "1 c" ]

Cependant, contrairement à l'utilisation de regexp.exec() dans une boucle, vous ne pouvez pas modifier lastIndex pour faire avancer ou reculer l'expression rationnelle.

Meilleur accès aux groupes capturant (que String.prototype.match())

Une autre raison importante d'utiliser matchAll est le meilleur accès aux groupes capturant.

Les groupes capturant sont ignorés lors de l'utilisation de match() avec l'indicateur global g :

js
const regexp = /t(e)(st(\d?))/g;
const chaine = "test1test2";

chaine.match(regexp); // ['test1', 'test2']

Avec matchAll, vous pouvez facilement accéder aux groupes capturant :

js
const tableau = [...chaine.matchAll(regexp)];

tableau[0];
// ['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', length: 4]
tableau[1];
// ['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', length: 4]

Utiliser matchAll() avec un objet autre qu'une expression rationnelle qui implémente [Symbol.matchAll]()

Si un objet possède une méthode Symbol.matchAll, il peut servir de moteur de correspondance personnalisé. La valeur de retour de Symbol.matchAll devient celle de matchAll().

js
const chaine = "Hmm, c'est intéressant.";

chaine.matchAll({
  [Symbol.matchAll](chaine) {
    return [["Oui, c'est intéressant."]];
  },
}); // retourne [["Oui, c'est intéressant."]]

Spécifications

Spécification
ECMAScript® 2027 Language Specification
# sec-string.prototype.matchall

Compatibilité des navigateurs

Voir aussi