2009-07-22 17 views
72

Dato questa funzione:sostituire JavaScript/regex

function Repeater(template) { 

    var repeater = { 

     markup: template, 

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

    }; 

    return repeater; 

}; 

Come faccio this.markup.replace() sostituire a livello globale? Ecco il problema Se lo uso così:

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

Il valore del allerta è "foobar $ TEST_ONE".

Se cambio Repeater a quanto segue, quindi nulla in sostituito in Chrome:

function Repeater(template) { 

    var repeater = { 

     markup: template, 

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

    }; 

    return repeater; 

}; 

... e l'avviso è $TEST_ONE $TEST_ONE.

risposta

102

è necessario fare doppio sfuggire alcun carattere RegExp (una volta per la barra nella stringa e una volta per la regexp):

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

In caso contrario, sembra per la fine della linea e 'TESTONE' (che non trova mai).

Personalmente, non sono un grande fan della costruzione di regexp utilizzando stringhe per questo motivo. Il livello di fuga di cui hai bisogno potrebbe portarti a bere. Sono sicuro che gli altri si sentano in modo diverso però e amano bere quando scrivono regex.

+0

Ma replace() riceve l'espressione regolare come variabile. – core

+0

Correzione minore - '$' indica fine riga in un'espressione regolare. – harto

+6

@Chris - Non penso che faccia la differenza se usi '/ pattern /' o 'new RegExp (" pattern ")'. – harto

21

vostro schema di espressione regolare dovrebbe avere il modificatore di g:

var pattern = /[somepattern]+/g; 

preavviso la g alla fine. dice al sostituto di fare una sostituzione globale.

Inoltre non è necessario utilizzare l'oggetto RegExp è possibile creare il modello come sopra. Reticolo Esempio:

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

un modello è sempre circondato da/su entrambi i lati - con modificatori dopo la finale /, il modificatore essendo g globale.

MODIFICA: Perché è importante se il modello è una variabile? Nel tuo caso sarebbe funzionare come questo (notare che modello è ancora una variabile):

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

Ma si avrebbe bisogno di cambiare il vostro sostituire la funzione a questo:

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

In termini di interpretazione del modello, non c'è alcuna differenza tra le seguenti forme:

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

Se si desidera sostituire una stringa letterale con il metodo replace, penso che si può solo passare una stringa invece di un regexp per replace.

In caso contrario, si avrebbe dovuto sfuggire caratteri speciali regexp nel modello prima - forse in questo modo:

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

// ... 

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

Non sapevo prima che/pattern/è uguale al nuovo RegExp ("pattern"). Davvero aiutato! –

+1

Qualche motivo per non utilizzare una lista bianca invece di una lista nera? ad esempio: s.replace (/ (\ W)/g, '\\ $ 1') –

+1

Il primo modulo elencato è migliore. È buona norma evitare la parola chiave _new_. – Druska