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

RegExp : méthode [Symbol.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 [Symbol.matchAll]() des instances de RegExp définit comment String.prototype.matchAll() doit se comporter.

Exemple interactif

class MyRegExp extends RegExp {
  [Symbol.matchAll](str) {
    const result = RegExp.prototype[Symbol.matchAll].call(this, str);
    if (!result) {
      return null;
    }
    return Array.from(result);
  }
}

const re = new MyRegExp("-\\d+", "g");
console.log("2016-01-02|2019-03-07".matchAll(re));
// Résultat attendu : Array [Array ["-01"], Array ["-02"], Array ["-03"], Array ["-07"]]

Syntaxe

js
regexp[Symbol.matchAll](str)

Paramètres

str

Une chaîne de caractères (String) dont on souhaite trouver les correspondances.

Valeur de retour

Un objet d'itérateur itérable (qui n'est pas possible de redémarrer) de correspondances. Chaque correspondance est un tableau ayant la même structure que la valeur de retour de RegExp.prototype.exec().

Description

Cette méthode permet de personnaliser le comportement de matchAll() dans les sous-classes de RegExp. Elle est appelée en interne dans String.prototype.matchAll(). Par exemple, les deux exemples suivants retournent le même résultat.

js
"abc".matchAll(/a/g);

/a/g[Symbol.matchAll]("abc");

Comme [Symbol.split](), [Symbol.matchAll]() commence par utiliser [Symbol.species] pour construire une nouvelle expression rationnelle, évitant ainsi de modifier l'expression rationnelle d'origine de quelque manière que ce soit. Le constructeur reçoit this et les indicateurs d'origine. lastIndex prend la valeur de l'expression rationnelle d'origine.

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

Si l'expression rationnelle est globale (avec l'indicateur g), chaque appel à la méthode next() de l'itérateur retourné appelle exec() de l'expression rationnelle et produit le résultat. Si la correspondance actuelle est une chaîne de caractères vide, lastIndex avance tout de même. Si l'expression rationnelle possède l'indicateur u, elle avance d'un point de code Unicode ; sinon, elle avance d'un point de code UTF-16.

js
console.log(Array.from("😄".matchAll(/(?:)/g)));
// [ [ "" ], [ "" ], [ "" ] ]

console.log(Array.from("😄".matchAll(/(?:)/gu)));
// [ [ "" ], [ "" ] ]

Si l'expression rationnelle n'est pas globale, l'itérateur retourné produit le résultat de exec() une seule fois, puis se termine. (La validation qui vérifie que l'entrée est une expression rationnelle globale a lieu dans String.prototype.matchAll(). [Symbol.matchAll]() ne valide pas les indicateurs de this.)

Lorsque l'expression rationnelle est adhérente et globale, elle effectue toujours des correspondances adhérentes — c'est-à-dire qu'elle ne trouve aucune occurrence au-delà de lastIndex.

js
console.log(Array.from("ab-c".matchAll(/[abc]/gy)));
// [ [ "a" ], [ "b" ] ]

Exemples

Appel direct

Cette méthode peut être utilisée de manière presque identique à String.prototype.matchAll(), sauf que l'objet this est différent et que l'ordre des arguments est également différent.

js
const re = /\d+/g;
const chaine = "2016-01-02";
const resultat = re[Symbol.matchAll](chaine);

console.log(Array.from(resultat, (x) => x[0]));
// [ "2016", "01", "02" ]

Utiliser [Symbol.matchAll]() dans les sous-classes

Les sous-classes de RegExp peuvent remplacer la méthode [Symbol.matchAll]() pour modifier le comportement par défaut.

Par exemple, pour retourner un tableau (Array) plutôt qu'un itérateur :

js
class MaRegExp extends RegExp {
  [Symbol.matchAll](chaine) {
    const resultat = RegExp.prototype[Symbol.matchAll].call(this, chaine);
    return resultat ? Array.from(resultat) : null;
  }
}

const re = new MaRegExp("(\\d+)-(\\d+)-(\\d+)", "g");
const chaine = "2016-01-02|2019-03-07";
const resultat = chaine.matchAll(re);

console.log(resultat[0]);
// [ "2016-01-02", "2016", "01", "02" ]

console.log(resultat[1]);
// [ "2019-03-07", "2019", "03", "07" ]

Spécifications

Spécification
ECMAScript® 2027 Language Specification
# sec-regexp-prototype-%symbol.matchall%

Compatibilité des navigateurs

Voir aussi