JavaScript değiştirme / regex


113

Bu işlev göz önüne alındığında:

function Repeater(template) {

    var repeater = {

        markup: template,

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

    };

    return repeater;

};

this.markup.replace()Global olarak nasıl değiştirebilirim? İşte sorun. Bunu böyle kullanırsam:

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

Uyarının değeri "foobar $ TEST_ONE" dir.

Ben değiştirirseniz Repeateraşağıda, Chrome'da yerini daha sonra hiçbir şey:

function Repeater(template) {

    var repeater = {

        markup: template,

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

    };

    return repeater;

};

... ve uyarı $TEST_ONE $TEST_ONE.

Yanıtlar:


147

Herhangi bir RegExp karakterinden çift çıkış yapmanız gerekir (bir kez dizedeki eğik çizgi için ve bir kez de normal ifade için):

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

Aksi takdirde, satırın sonunu ve 'TESTONE' (asla bulamadığı) arar.

Kişisel olarak, bu nedenle dizeleri kullanarak regexp oluşturmanın büyük bir hayranı değilim. İhtiyaç duyulan kaçış seviyesi sizi içmeye yönlendirebilir. Eminim ki diğerleri farklı hisseder ve normal ifadeler yazarken içmeyi sever.


Ancak replace (), normal ifadeyi değişken olarak alır.
çekirdek

8
@Chris - /pattern/veya kullanmanın bir fark yaratacağını sanmıyorum new RegExp("pattern").
harto

@seth, Cevabınız çalışıyor, ancak OP'den gelen koda bir çözüm sağlamıyor. OP'nin kodunu nasıl çağırmalıyım?
Kara

82

Kalıp yorumlama açısından, aşağıdaki biçimler arasında hiçbir fark yoktur:

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

replaceYöntemi kullanarak değişmez bir dizeyi değiştirmek istiyorsanız , bir regexp yerine bir dize geçirebileceğinizi düşünüyorum replace.

Aksi takdirde, önce kalıptaki herhangi bir regexp özel karakterinden kaçınmanız gerekir - belki şu şekilde:

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

// ...

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

12
Daha önce bilmiyordum, / pattern / yeni RegExp ("kalıp") ile aynıdır. Gerçekten yardımcı oldu!
Nik Sumeiko

1
Kara liste yerine beyaz liste kullanmamak için herhangi bir neden var mı? örneğin: s.replace (/ (\ W) / g, '\\ $ 1')
greg.kindel

1
Listelenen ilk form daha iyidir. Yeni anahtar kelimeden kaçınmak iyi bir uygulamadır .
Druska

2
Normal ifade değişmezinin (/ regex /) RegExp ("regex") ile aynı olduğunu söylemek doğru değildir. Normal ifade değişmezinde, normal ifadenin bir parçası olabilmesi için ters-katılaşmanın ('\') kendisinin kaçması ('\\') gerekmez. Ayrıca, normal ifade değişmezi, işlev her çalıştırıldığında değil, kod ayrıştırıldığında derlenebilir. Bir ters katılaşmayı eşleştirmek için / \\ / veya RexExp ("\\\\") yazabilirsiniz.
John

31

Normal ifade kalıbınız g değiştiriciye sahip olmalıdır:

var pattern = /[somepattern]+/g;

sonunda g'ye dikkat edin. değiştiriciye genel bir değiştirme yapmasını söyler.

Ayrıca, modelinizi yukarıdaki gibi oluşturabileceğiniz RegExp nesnesini kullanmanıza gerek yoktur. Örnek desen:

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

bir desen her zaman her iki tarafta / ile çevrelenir - son / 'dan sonra değiştiricilerle, g değiştiricisi ise globaldir.

DÜZENLEME: Modelin değişken olması neden önemlidir? Sizin durumunuzda, şu şekilde çalışacaktır (modelin hala bir değişken olduğuna dikkat edin):

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

Ancak değiştirme işlevinizi şu şekilde değiştirmeniz gerekir:

this.markup = this.markup.replace(pattern, value);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.