JavaScript置換/正規表現


113

この関数を考えると:

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

回答:


147

RegExp文字をダブルエスケープする必要があります(文字列のスラッシュの場合は1回、正規表現の場合は1回)。

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

それ以外の場合は、行の終わりと 'TESTONE'(これは検出されません)を探します。

個人的には、この理由で文字列を使用して正規表現を構築するのはあまり好きではありません。必要な脱出のレベルは、あなたを飲みに導くかもしれません。他の人も違った感じで正規表現を書くときに飲んでみたいと思います。


しかし、replace()は正規表現を変数として受け取ります。
コア、

8
@Chris- /pattern/またはを使用しても違いはないと思いますnew RegExp("pattern")
harto 2009

@seth、あなたの答えは機能しますが、OPからのコードに対する解決策を提供しません。OPのコードを呼び出す方法を教えてください。
ブラック

82

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

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

12
/ pattern /は新しいRegExp( "pattern")と同じであることを以前は知りませんでした。本当に役に立ちました!
Nik Sumeiko、2011

1
ブラックリストの代わりにホワイトリストを使用しない理由はありますか?例:s.replace(/(\ W)/ g、 '\\ $ 1')
greg.kindel

1
リストされている最初のフォームの方が優れています。新しいキーワードを使用しないことをお勧めします。
ドルスカ2013

2
正規表現リテラル(/ regex /)がRegExp( "regex")と同じであると言うのは正確ではありません。正規表現リテラルでは、逆ソリダス( '\')を正規表現の一部にするために、それ自体をエスケープする必要はありません( '\\')。さらに、正規表現リテラルは、関数が実行されるたびではなく、スクリプトが解析されるときにコンパイルできます。逆ソリダスと一致させるには、/ \\ /またはRexExp( "\\\\")と記述します。
John

31

正規表現パターンには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);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.