JavaScript replace/regex

Учитывая эту функцию:

function Repeater(template) {

    var repeater = {

        markup: template,

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

    };

    return repeater;

};

Как мне заменить this.markup.replace() глобально? Вот проблема. Если я использую его так:

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

Значение предупреждения - "foobar $TEST_ONE".

Если я изменяю Repeater на следующее, то ничего не заменяется в Chrome:

function Repeater(template) {

    var repeater = {

        markup: template,

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

    };

    return repeater;

};

... и предупреждение $TEST_ONE $TEST_ONE.

Ответ 1

Вам нужно удвоить escape любых символов RegExp (один раз для косой черты в строке и один раз для регулярного выражения):

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

В противном случае он ищет конец строки и "TESTONE" (который он никогда не находит).

Лично я не большой поклонник создания regexp с использованием строк по этой причине. Уровень побега, который вам нужен, может заставить вас выпить. Я уверен, что другие чувствуют себя иначе, и любят пить при написании регулярных выражений.

Ответ 2

В терминах интерпретации шаблонов нет разницы между следующими формами:

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

Если вы хотите заменить литеральную строку с помощью метода replace, я думаю, вы можете просто передать строку вместо регулярного выражения в replace.

В противном случае вам придется избегать любых специальных символов регулярного выражения в шаблоне вначале - возможно, так:

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

// ...

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

Ответ 3

Ваш шаблон регулярного выражения должен иметь модификатор g:

var pattern = /[somepattern]+/g;

обратите внимание на g в конце. он сообщает замену заменить глобальную замену.

Также вам не нужно использовать объект RegExp, который вы можете построить, как показано выше. Пример шаблона:

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

шаблон всегда окружен/с каждой стороны - с модификаторами после окончательного /, модификатор g является глобальным.

EDIT: Почему имеет значение, если шаблон является переменной? В вашем случае он будет работать так (обратите внимание, что шаблон все еще является переменной):

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

Но вам нужно изменить функцию замены на это:

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