2009-07-22 23 views
72

diese Funktion Gegeben:JavaScript ersetzen/regex

function Repeater(template) { 

    var repeater = { 

     markup: template, 

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

    }; 

    return repeater; 

}; 

Wie kann ich this.markup.replace() global ersetzen machen? Hier ist das Problem. Wenn ich es so verwende:

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

Der Wert der Warnung ist "Foobar $ TEST_ONE".

Wenn ich Repeater der folgenden ändern, dann nichts in Chrome ersetzt:

function Repeater(template) { 

    var repeater = { 

     markup: template, 

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

    }; 

    return repeater; 

}; 

... und die Warnung ist $TEST_ONE $TEST_ONE.

Antwort

102

Sie müssen alle RegExp Zeichen verdoppeln zu entkommen (einmal für den Schrägstrich im String und einmal für die regexp):

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

Ansonsten sieht es für das Ende der Zeile und ‚testone‘ (die es findet nie).

Persönlich bin ich kein großer Fan von Regexp Strings aus diesem Grund zu verwenden. Das Niveau der Flucht, die benötigt wird, könnte Sie dazu bringen, zu trinken. Ich bin mir sicher, dass andere sich anders fühlen und gerne trinken, wenn sie Regexes schreiben.

+0

Aber replace() erhält die Regex als Variable. – core

+0

Geringfügige Korrektur - '$ 'bezeichnet das Ende der Zeile in einem regulären Ausdruck. – harto

+6

@Chris - Ich denke nicht, dass es einen Unterschied macht, wenn Sie '/ pattern /' oder 'new RegExp (" pattern ")' verwenden. – harto

21

Ihre RegexMuster sollte g Modifier:

var pattern = /[somepattern]+/g; 

Mitteilung der g am Ende. es sagt dem Ersetzer, dass er eine globale Ersetzung durchführen soll.

Sie müssen auch nicht das RegExp Objekt verwenden, Sie können Ihr Muster wie oben erstellen. Beispielmuster:

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

ein Muster immer von/auf beiden Seiten umgeben ist - mit Modifikatoren nach dem letzten /, dem g-Modifikator der global sein.

EDIT: Warum ist es wichtig, wenn Muster eine Variable ist? In Ihrem Fall würde es so funktionieren (beachten Sie, dass Muster noch eine Variable ist):

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

Aber Sie müssten Ihre Funktion diese ersetzen ändern:

this.markup = this.markup.replace(pattern, value); 
55

In Bezug auf die Muster Interpretation, gibt es keinen Unterschied zwischen den folgenden Formen:

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

Wenn Sie eine Zeichenkette mit der replace Methode ersetzen wollen, ich glaube, Sie nur einen String statt eines regulären Ausdruck replace passieren kann.

Andernfalls würden Sie zuerst alle regexp Sonderzeichen im Muster entkommen müssen - vielleicht etwa so:

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

// ... 

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

Wusste vorher nicht, dass/pattern/ist das gleiche wie neue RegExp ("Muster"). Wirklich geholfen! –

+1

Gibt es einen Grund, keine Whitelist anstelle einer Blacklist zu verwenden? zB: s.replace (/ (\ W)/g, '\\ $ 1') –

+1

Die erste aufgelistete Form ist besser. Es empfiehlt sich, das Schlüsselwort _new_ zu vermeiden. – Druska

Verwandte Themen