Substituição/expressão regular do JavaScript
dada esta função:
function Repeater(template) {
var repeater = {
markup: template,
replace: function(pattern, value) {
this.markup = this.markup.replace(pattern, value);
}
};
return repeater;
};
Como faço para que this.markup.replace()
Substitua globalmente? Eis o problema. Se eu o usar assim:
alert(new Repeater("$TEST_ONE $TEST_ONE").replace("$TEST_ONE", "foobar").markup);
O valor do alerta é "foobar $ TEST_ONE".
Se eu mudar Repeater
para o seguinte, então nada em substituído no cromado:
function Repeater(template) {
var repeater = {
markup: template,
replace: function(pattern, value) {
this.markup = this.markup.replace(new RegExp(pattern, "gm"), value);
}
};
return repeater;
};
...e o alerta é $TEST_ONE $TEST_ONE
3 answers
Tem de escapar de forma dupla a quaisquer caracteres de expressão regular (uma vez para a barra no texto e outra para a expressão regular):
"$TESTONE $TESTONE".replace( new RegExp("\\$TESTONE","gm"),"foo")
Caso contrário, procura o fim da linha e "TESTONE" (que nunca encontra).
Pessoalmente, não sou grande fã de construir a regexp a usar cordas por esta razão. O nível de fuga que é necessário pode levar-te a beber. Tenho a certeza que os outros se sentem diferentes e gostam de beber quando escrevem regexes.
Em termos de interpretação de padrões, não há diferença entre as seguintes formas:
/pattern/
new RegExp("pattern")
Se quiser substituir uma string literal usando o método replace
, acho que pode passar uma string em vez de uma regexp para replace
.
function reEscape(s) {
return s.replace(/([.*+?^$|(){}\[\]])/mg, "\\$1");
}
// ...
var re = new RegExp(reEscape(pattern), "mg");
this.markup = this.markup.replace(re, value);
O seu padrão regex deve ter o modificador g:
var pattern = /[somepattern]+/g;
Repara no g no fim. ele diz ao substituto para fazer uma substituição global.
Também não precisa de usar o objecto RegExp que pode construir o seu padrão como acima. Exemplo padrão:
var pattern = /[0-9a-zA-Z]+/g;
Um padrão é sempre rodeado por / de cada lado - com modificadores após o / final, sendo o modificador g o global.
Editar: porque é que importa se o padrão é uma variável? No teu caso, sim. função como esta (repare que o padrão ainda é uma variável):
var pattern = /[0-9a-zA-Z]+/g;
repeater.replace(pattern, "1234abc");
Mas teria de mudar a sua função de substituição para esta:
this.markup = this.markup.replace(pattern, value);