Chciałbym utworzyć metodę String.replaceAll() w JavaScript i myślę, że korzystanie z regexa byłoby najbardziej wymagającym sposobem. Nie mogę jednak dowiedzieć się, jak przekazać zmienną do REGEX. Mogę to zrobić już, który zastąpi wszystkie instancje "B" za pomocą "A".

"ABABAB".replace(/B/g, "A");

Ale chcę coś zrobić w ten sposób:

String.prototype.replaceAll = function(replaceThis, withThis) {
    this.replace(/replaceThis/g, withThis);
};

Ale oczywiście to zastąpi tylko tekst "replaceThis" ... więc jak minąć tę zmienną do mojego łańcucha regexa?

1643
JC Grubbs 30 styczeń 2009, 03:11

18 odpowiedzi

Najlepsza odpowiedź

Zamiast używać składni /regex/g, możesz skonstruować nową REGEXP obiekt:

var replace = "regex";
var re = new RegExp(replace,"g");

Możesz dynamicznie tworzyć obiekty regex w ten sposób. Wtedy zrobisz:

"mystring".replace(re, "newstring");
2008
jcubic 17 grudzień 2016, 09:53
String.prototype.replaceAll = function(a, b) {
    return this.replace(new RegExp(a.replace(/([.?*+^$[\]\\(){}|-])/ig, "\\$1"), 'ig'), b)
}

Sprawdź to jak:

var whatever = 'Some [b]random[/b] text in a [b]sentence.[/b]'

console.log(whatever.replaceAll("[", "<").replaceAll("]", ">"))
6
MetalGodwin 20 sierpień 2013, 12:35

Aby zaspokoić potrzebę wstawienia zmiennej / aliasu / funkcji do wyrażenia regularnego, to właśnie wymyśliłem:

oldre = /xx\(""\)/;
function newre(e){
    return RegExp(e.toString().replace(/\//g,"").replace(/xx/g, yy), "g")
};

String.prototype.replaceAll = this.replace(newre(oldre), "withThis");

Gdzie "Oldre" jest oryginalnym REGEXP, że chcę wstawić zmienną, "XX" jest zastępczem dla tej zmiennej / aliasu / funkcji, a "YY" jest rzeczywistą nazwą zmienną, alias lub funkcją.

5
Alex Li 5 czerwiec 2013, 04:38

A wersja Coffeescriptowa odpowiedzi Steven Penny, ponieważ jest to # 2 wynik Google .... Nawet jeśli kawa jest właśnie javascript z dużą ilością znaków usuniętych ...;)

baz = "foo"
filter = new RegExp(baz + "d")
"food fight".match(filter)[0] // food

Iw mojej konkretnej sprawie

robot.name=hubot
filter = new RegExp(robot.name)
if msg.match.input.match(filter)
  console.log "True!"
5
keen 29 październik 2015, 15:49

Oto kolejna implementacja Wymiennika:

    String.prototype.replaceAll = function (stringToFind, stringToReplace) {
        if ( stringToFind == stringToReplace) return this;
        var temp = this;
        var index = temp.indexOf(stringToFind);
        while (index != -1) {
            temp = temp.replace(stringToFind, stringToReplace);
            index = temp.indexOf(stringToFind);
        }
        return temp;
    };
4
scripto 8 maj 2013, 10:30

Chociaż możesz wykonać dynamicznie stworzony Regexp (zgodnie z innymi reakcjami na to pytanie), echmentuję mój komentarz z Podobny post: Funkcjonalna forma String.replace () jest niezwykle przydatny iw wielu przypadkach zmniejsza potrzebę dynamicznie utworzonych obiektów REGEXP. (które są rodzajem bólu, ponieważ musisz wyrazić wejście do konstruktora REGEXP jako ciąg, zamiast używać slashes / [A-Z] + / regexp dosłownego formatu)

3
Community 23 maj 2017, 12:10

Możesz użyć tego, jeśli $ 1 nie działa z tobą

var pattern = new RegExp("amman","i");
"abc Amman efg".replace(pattern,"<b>"+"abc Amman efg".match(pattern)[0]+"</b>");
3
Fareed Alnamrouti 13 czerwiec 2013, 11:13

Ta funkcja samozapierająca wywołuje się do wymiany liczby za pomocą indeksu i zmień wymianę [Indeks] na całym świecie na łańcuchu z każdym przejściem.

  const replacerItems = ["a", "b", "c"];    

    function replacer(str, index){
          const item = replacerItems[index];
          const regex = new RegExp(`[${item}]`, "g");
          const newStr = str.replace(regex, "z");
          if (index < replacerItems.length - 1) {
            return replacer(newStr, index + 1);
          }
          return newStr;
    }

// console.log(replacer('abcdefg', 0)) will output 'zzzdefg'
3
user8094098user8094098 16 grudzień 2019, 17:24

Zawsze możesz być zawsze używany indexOf:

String.prototype.replaceAll = function(substring, replacement) {
    var result = '';
    var lastIndex = 0;

    while(true) {
        var index = this.indexOf(substring, lastIndex);
        if(index === -1) break;
        result += this.substring(lastIndex, index) + replacement;
        lastIndex = index + substring.length;
    }

    return result + this.substring(lastIndex);
};

Nie pasuje do nieskończonej pętli, gdy wymiana zawiera mecz.

2
Ry- 16 sierpień 2013, 19:53

W przypadku wielokrotnego zastąpienia bez wyrażeń regularnych poszedłem z następującymi:

      let str = "I am a cat man. I like cats";
      let find = "cat";
      let replace = "dog";


      // Count how many occurrences there are of the string to find 
      // inside the str to be examined.
      let findCount = str.split(find).length - 1;

      let loopCount = 0;

      while (loopCount < findCount) 
      {
        str = str.replace(find, replace);
        loopCount = loopCount + 1;
      }  

      console.log(str);
      // I am a dog man. I like dogs

Znaleziono ważną część rozwiązania

0
John Shearing 24 listopad 2019, 01:52

Jak wspomniano Eric Wendelin, możesz zrobić coś takiego:

str1 = "pattern"
var re = new RegExp(str1, "g");
"pattern matching .".replace(re, "regex");

To daje "regex matching .". Jednak nie powiedzie się, jeśli str1 jest ".". Spodziewasz się, że wynik jest "pattern matching regex", zastępując okres z "regex", ale okaże się ...

regexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregex

Dzieje się tak dlatego, że, chociaż "." jest ciągiem, w konstruktorze REGEXP nadal interpretowany jako wyrażenie regularne, co oznacza dowolny znak przerwy bez linii, co oznacza każdą postać w ciągu. W tym celu przydatne może być następująca funkcja:

 RegExp.quote = function(str) {
     return str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
 };

Następnie możesz:

str1 = "."
var re = new RegExp(RegExp.quote(str1), "g");
"pattern matching .".replace(re, "regex");

Uzyskując "pattern matching regex".

222
Qtax 19 czerwiec 2012, 08:15

"ABABAB".replace(/B/g, "A");

Jak zawsze: nie używaj regexa, chyba że musisz. Aby uzyskać prosty strun, idiom jest:

'ABABAB'.split('B').join('A')

Wtedy nie musisz się martwić o kwestie cytowania wymienione w odpowiedzi Gracentes.

120
Liam 30 styczeń 2018, 11:45

Jeśli chcesz uzyskać wszystkie wystąpienia (g), być niewrażliwe ({x1}}) i użyj granic, aby nie było słowem w innym słowie ({x2}}):

re = new RegExp(`\\b${replaceThis}\\b`, 'gi');

Przykład:

let inputString = "I'm John, or johnny, but I prefer john.";
let replaceThis = "John";
let re = new RegExp(`\\b${replaceThis}\\b`, 'gi');
console.log(inputString.replace(re, "Jack")); // I'm Jack, or johnny, but I prefer Jack.
51
JBallin 13 czerwiec 2018, 02:52

Dla każdego, kto chce użyć zmiennej z metodą mecz , to działało dla mnie

var alpha = 'fig';
'food fight'.match(alpha + 'ht')[0]; // fight
36
Steven Penny 9 maj 2015, 17:48

To:

var txt=new RegExp(pattern,attributes);

Jest równoważne z tym:

var txt=/pattern/attributes;

Zobacz http://www.w3schools.com/jsref/jsref_obj_regexp.asp.

33
Jeremy Ruten 30 styczeń 2009, 00:19
this.replace( new RegExp( replaceThis, 'g' ), withThis );
28
Mike Samuel 16 styczeń 2012, 16:22

Dynamicznie zbudować wyrażenie regularne, a dla tego właściwy solucja jest użycie konstruktora new RegExp(string). Aby konstruktor traktuje znaki specjalne dosłownie , musisz je uciec. Istnieje wbudowana funkcja w Widget autouzupełniający jQuery ui o nazwie $.ui.autocomplete.escapeRegex:

[...] Możesz skorzystać z wbudowanego $.ui.autocomplete.escapeRegex Funkcja. To zrobi pojedynczy ciąg argument i uciekaj wszystkie znaki regexa, dzięki czemu wynik jest bezpieczny Przejdź do new RegExp().

Jeśli używasz JQuery UI, możesz użyć tej funkcji lub skopiować jego definicję ze źródła:

function escapeRegex( value ) {
    return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
}

I użyj tego w ten sposób:

"[z-a][z-a][z-a]".replace(new RegExp(escapeRegex("[z-a]"), "g"), "[a-z]");
//            escapeRegex("[z-a]")       -> "\[z\-a\]"
// new RegExp(escapeRegex("[z-a]"), "g") -> /\[z\-a\]/g
// end result                            -> "[a-z][a-z][a-z]"
16
Salman A 21 sierpień 2019, 13:33
String.prototype.replaceAll = function (replaceThis, withThis) {
   var re = new RegExp(replaceThis,"g"); 
   return this.replace(re, withThis);
};
var aa = "abab54..aba".replaceAll("\\.", "v");

Testuj z tym Narzędzie

10
unigogo 1 luty 2009, 09:28