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.replace]()

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.replace]() des instances de RegExp définit comment String.prototype.replace() et String.prototype.replaceAll() doivent se comporter lorsque l'expression rationnelle est passée en tant que motif.

Exemple interactif

class RegExp1 extends RegExp {
  [Symbol.replace](str) {
    return RegExp.prototype[Symbol.replace].call(this, str, "#!@?");
  }
}

console.log("tototruc".replace(new RegExp1("toto")));
// Résultat attendu : "#!@?truc"

Syntaxe

js
regexp[Symbol.replace](str, replacement)

Paramètres

str

Une chaîne de caractères (String) qui est la cible du remplacement.

replacement

Peut être une chaîne de caractères ou une fonction.

  • Si c'est une chaîne de caractères, elle remplace la sous-chaîne de caractère correspondant à l'expression rationnelle actuelle. Un certain nombre de modèles de remplacement spéciaux sont pris en charge ; voir la section Définir une chaîne de caractères comme remplacement de String.prototype.replace.
  • Si c'est une fonction, elle est invoquée pour chaque correspondance et la valeur de retour est utilisée comme texte de remplacement. Les arguments fournis à cette fonction sont décrits dans la section Définir une fonction comme remplacement de String.prototype.replace.

Valeur de retour

Une nouvelle chaîne de caractères, avec une, plusieurs ou toutes les correspondances du motif remplacées par le remplacement défini.

Description

Cette méthode existe pour personnaliser le comportement du remplacement dans les sous-classes de RegExp. Elle est appelée en interne dans String.prototype.replace() et String.prototype.replaceAll() si l'argument pattern est un objet RegExp. Par exemple, les deux exemples suivants retournent le même résultat.

js
"abc".replace(/a/, "A");

/a/[Symbol.replace]("abc", "A");

Si l'expression rationnelle est globale (avec l'indicateur g), son lastIndex est d'abord défini à 0, de sorte que la recherche commence toujours au début de la chaîne de caractères, et sa méthode exec() est appelée à plusieurs reprises jusqu'à ce que exec() retourne null. Si la correspondance actuelle est une chaîne de caractères vide, lastIndex avance tout de même — si l'expression rationnelle est compatible avec Unicode, elle avance d'un point de code Unicode ; sinon, elle avance d'une unité de code UTF-16.

js
console.log("😄".replace(/(?:)/g, " ")); // " \ud83d \ude04 "
console.log("😄".replace(/(?:)/gu, " ")); // " 😄 "

Si l'expression rationnelle n'est pas globale, exec() ne serait appelée qu'une seule fois.

La substitution a lieu après que toutes les sous-chaînes de caractères correspondantes ont été identifiées. Pour chaque résultat réussi de exec(), une chaîne de caractères de substitution est créée à partir de l'argument replacement, le processus est décrit dans String.prototype.replace().

La méthode exec() réinitialise automatiquement lastIndex à 0 lorsque la dernière correspondance échoue, ainsi, pour les expressions rationnelles globales dont lastIndex commence à 0, [Symbol.replace]() ne produit généralement aucun effet secondaire. Cependant, lorsque l'expression rationnelle est adhérente mais n'est pas globale, exec() n'est appelée qu'une seule fois et ne réinitialise donc pas lastIndex si la correspondance a réussi. Dans ce cas, chaque appel à replace() peut retourner un résultat différent.

js
const re = /a/y;

for (let i = 0; i < 5; i++) {
  console.log("aaa".replace(re, "b"), re.lastIndex);
}

// baa 1
// aba 2
// aab 3
// aaa 0
// baa 1

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("aa-a".replace(/a/gy, "b")); // "bb-a"

Exemples

Appel direct

Cette méthode peut être utilisée de manière presque identique à String.prototype.replace(), à l'exception du this différent et de l'ordre des arguments différent.

js
const re = /-/g;
const chaine = "2016-01-01";
const nouvelleChaine = re[Symbol.replace](chaine, ".");
console.log(nouvelleChaine); // 2016.01.01

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

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

js
class MaRegExp extends RegExp {
  constructor(motif, indicateurs, compte) {
    super(motif, indicateurs);
    this.count = compte;
  }
  [Symbol.replace](chaine, remplacement) {
    // Effectue [Symbol.replace]() `count` fois.
    let resultat = chaine;
    for (let i = 0; i < this.count; i++) {
      resultat = RegExp.prototype[Symbol.replace].call(
        this,
        resultat,
        remplacement,
      );
    }
    return resultat;
  }
}

const re = new MaRegExp("\\d", "", 3);
const chaine = "01234567";
const nouvelleChaine = chaine.replace(re, "#"); // String.prototype.replace appelle re[Symbol.replace]().
console.log(nouvelleChaine); // ###34567

Spécifications

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

Compatibilité des navigateurs

Voir aussi