web-dev-qa-db-ja.com

JavaScriptの置換/正規表現

この関数を考えます:

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です。

95
core

RegExp文字を二重にエスケープする必要があります(文字列のスラッシュに対して1回、正規表現に対して1回):

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

それ以外の場合は、行末と「TESTONE」(検出されない)を探します。

個人的に、私はこの理由で文字列を使用して正規表現を構築することの大ファンではありません。必要なエスケープのレベルは、飲酒につながる可能性があります。しかし、他の人は違う感じで、正規表現を書くときは飲むのが好きだと思います。

126
seth

パターンの解釈に関しては、次の形式に違いはありません。

  • /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);
69
harto

正規表現パターンにはg修飾子が必要です。

var pattern = /[somepattern]+/g;

最後にgがあります。置換プログラムにグローバル置換を行うよう指示します。

また、上記のようにパターンを構築できるRegExpオブジェクトを使用する必要はありません。パターンの例:

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

パターンは常にどちらかの側で/で囲まれます-最後の/の後に修飾子があり、g修飾子はグローバルです。

編集:パターンが変数である場合、なぜ重要なのですか?あなたの場合、これは次のように機能します(パターンはまだ変数であることに注意してください):

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

ただし、replace関数を次のように変更する必要があります。

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