web-dev-qa-db-fra.com

JavaScript remplacer / regex

Étant donné cette fonction:

function Repeater(template) {

    var repeater = {

        markup: template,

        replace: function(pattern, value) {
            this.markup = this.markup.replace(pattern, value);
        }

    };

    return repeater;

};

Comment faire pour que this.markup.replace() soit remplacé globalement? Voici le problème. Si je l'utilise comme ça:

alert(new Repeater("$TEST_ONE $TEST_ONE").replace("$TEST_ONE", "foobar").markup);

La valeur de l'alerte est "foobar $ TEST_ONE".

Si je remplace Repeater par ce qui suit, rien ne sera remplacé dans Chrome:

function Repeater(template) {

    var repeater = {

        markup: template,

        replace: function(pattern, value) {
            this.markup = this.markup.replace(new RegExp(pattern, "gm"), value);
        }

    };

    return repeater;

};

... et l'alerte est $TEST_ONE $TEST_ONE.

95
core

Vous devez double échapper à tous les caractères RegExp (une fois pour la barre oblique et une fois pour l'expression rationnelle):

  "$TESTONE $TESTONE".replace( new RegExp("\\$TESTONE","gm"),"foo")

Sinon, il cherche la fin de la ligne et 'TESTONE' (qu'il ne trouve jamais).

Personnellement, je ne suis pas un grand fan de la construction de regexp utilisant des chaînes pour cette raison. Le niveau d'évasion nécessaire peut vous amener à boire. Je suis sûr que les autres se sentent différemment et aiment boire lors de la rédaction de regex.

126
seth

En termes d'interprétation des motifs, il n'y a pas de différence entre les formes suivantes:

  • /pattern/
  • new RegExp("pattern")

Si vous voulez remplacer une chaîne littérale à l'aide de la méthode replace, je pense que vous pouvez simplement passer une chaîne au lieu d'une expression rationnelle à replace.

Sinon, vous devriez d'abord échapper à tous les caractères spéciaux d'expressions rationnelles du motif - peut-être comme ceci:

function reEscape(s) {
    return s.replace(/([.*+?^$|(){}\[\]])/mg, "\\$1");
}

// ...

var re = new RegExp(reEscape(pattern), "mg");
this.markup = this.markup.replace(re, value);
69
harto

Votre motif de regex devrait avoir le modificateur g:

var pattern = /[somepattern]+/g;

remarquez le g à la fin. il demande au remplaçant d'effectuer un remplacement global.

De plus, vous n'avez pas besoin d'utiliser l'objet RegExp, vous pouvez construire votre modèle comme ci-dessus. Exemple de modèle:

var pattern = /[0-9a-zA-Z]+/g;

un motif est toujours entouré de/de chaque côté - avec des modificateurs après le dernier /, le modificateur g étant le global.

EDIT: Pourquoi est-il important que le motif soit une variable? Dans votre cas, cela fonctionnerait comme ceci (notez que le motif est toujours une variable):

var pattern = /[0-9a-zA-Z]+/g;
repeater.replace(pattern, "1234abc");

Mais vous devrez changer votre fonction de remplacement en ceci:

this.markup = this.markup.replace(pattern, value);
26
Darko Z