Vraag Hoe vervang ik alle occurrences van een string in JavaScript?


Ik heb deze string:

"Test abc test test abc test test test abc test test abc"

Aan het doen

str = str.replace('abc', '');

lijkt alleen de eerste occurrence van te verwijderen abc in de string hierboven. Hoe kan ik vervangen alle voorkomens ervan?


3164
2017-07-17 17:53


oorsprong


antwoorden:


Volledigheidshalve begon ik na te denken over de methode die ik zou moeten gebruiken om dit te doen. Er zijn in principe twee manieren om dit te doen, zoals gesuggereerd door de andere antwoorden op deze pagina.

Notitie: Over het algemeen wordt het niet aanbevolen om de ingebouwde prototypen in JavaScript uit te breiden. Ik verstrek als uitbreidingen op het String-prototype eenvoudig ter illustratie, met verschillende implementaties van een hypothetische standaardmethode op de String ingebouwd prototype.


Reguliere expressie gebaseerde implementatie

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.replace(new RegExp(search, 'g'), replacement);
};

Splitsen en samenvoegen (functionele) implementatie

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.split(search).join(replacement);
};

Omdat ik niet te veel wist over hoe reguliere uitdrukkingen achter de schermen werken op het gebied van efficiëntie, neigde ik ernaar om naar de splitsing te neigen en me bij de implementatie te voegen in het verleden zonder na te denken over de prestaties. Toen ik me afvroeg wat efficiënter was en met welke marge, gebruikte ik het als een excuus om erachter te komen.

Op mijn Chrome Windows 8-computer, de op reguliere expressie gebaseerde implementatie is de snelste, met de splitsen en aansluiten bij implementatie is 53% langzamer. Dit betekent dat de reguliere expressies twee keer zo snel zijn voor de lorem ipsum-invoer die ik heb gebruikt.

Kijk hier eens naar criterium deze twee implementaties tegen elkaar uit te voeren.


Zoals opgemerkt in de onderstaande opmerking door @ThomasLeduc en anderen, kan er een probleem zijn met de reguliere expressie-gebaseerde implementatie als search bevat bepaalde tekens die zijn gereserveerd als speciale karakters in reguliere expressies. De implementatie gaat ervan uit dat de beller vooraf aan de tekenreeks zal ontsnappen of alleen strings zonder de tekens in de tabel zal doorgeven Normale uitdrukkingen (MDN).

MDN biedt ook een implementatie om aan onze touwtjes te ontsnappen. Het zou leuk zijn als dit ook gestandaardiseerd was zoals RegExp.escape(str), maar helaas bestaat het niet:

function escapeRegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}

We kunnen bellen escapeRegExp binnen onze String.prototype.replaceAll implementatie, echter, ben ik niet zeker hoeveel dit de prestaties zal beïnvloeden (mogelijk zelfs voor reeksen waarvoor het ontsnappen niet nodig is, zoals alle alfanumerieke reeksen).


1627
2017-07-12 01:46



str = str.replace(/abc/g, '');

Als reactie op commentaar:

var find = 'abc';
var re = new RegExp(find, 'g');

str = str.replace(re, '');

Als reactie op Klik op Upvote's opmerking, je zou het nog eenvoudiger kunnen maken:

function replaceAll(str, find, replace) {
    return str.replace(new RegExp(find, 'g'), replace);
}

Notitie: Reguliere expressies bevatten speciale (meta) karakters, en als zodanig is het gevaarlijk om blindelings een argument in de find functie hierboven zonder deze vooraf te verwerken om aan die tekens te ontsnappen. Dit wordt behandeld in de Mozilla Developer Network's JavaScript-gids voor reguliere expressies, waar ze de volgende utiliteitsfunctie presenteren:

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

Dus om het te maken replaceAll() functie boven veiliger, zou het kunnen worden gewijzigd in het volgende als u ook opneemt escapeRegExp:

function replaceAll(str, find, replace) {
    return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}

3586
2017-07-17 17:54



Opmerking: gebruik dit niet in echte code.

Als alternatief voor reguliere expressies voor een eenvoudige letterlijke tekenreeks, zou u deze kunnen gebruiken

str = "Test abc test test abc test...".split("abc").join("");

Het algemene patroon is

str.split(search).join(replacement)

In sommige gevallen was dit vroeger sneller dan het gebruik replaceAll en een reguliere expressie, maar dat lijkt niet meer het geval te zijn in moderne browsers. Dus dit zou eigenlijk alleen moeten worden gebruikt als een snelle hack om te voorkomen dat je aan de reguliere expressie moet ontsnappen, niet in echte code.


1193
2017-07-17 20:29



Een reguliere expressie gebruiken met de g vlag set zal alles vervangen:

someString = 'the cat looks like a cat';
anotherString = someString.replace(/cat/g, 'dog');
// anotherString now contains "the dog looks like a dog"

Zie hier ook


505
2018-05-06 23:18



Hier is een string-prototypefunctie gebaseerd op het geaccepteerde antwoord:

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find, 'g'), replace);
};

BEWERK 

Als jouw find bevat speciale tekens, dan moet je eraan ontsnappen:

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};

Viool: http://jsfiddle.net/cdbzL/


90
2018-02-11 23:03



Bijwerken:

Het is enigszins laat voor een update, maar aangezien ik deze vraag toevallig tegenkwam, merkte ik dat mijn vorige antwoord niet een is waar ik blij mee ben. Omdat de vraag bestond uit het vervangen van een enkel woord, is het ongelooflijk dat niemand dacht om woordgrenzen te gebruiken (\b)

'a cat is not a caterpillar'.replace(/\bcat\b/gi,'dog');
//"a dog is not a caterpillar"

Dit is een eenvoudige regex die voorkomt dat delen van woorden in de meeste gevallen worden vervangen. Echter, een streepje - wordt nog steeds beschouwd als een woordgrens. In dit geval kunnen dus conditionals worden gebruikt om te voorkomen dat strings zoals worden vervangen cool-cat:

'a cat is not a cool-cat'.replace(/\bcat\b/gi,'dog');//wrong
//"a dog is not a cool-dog" -- nips
'a cat is not a cool-cat'.replace(/(?:\b([^-]))cat(?:\b([^-]))/gi,'$1dog$2');
//"a dog is not a cool-cat"

in principe is deze vraag hetzelfde als de vraag hier: Javascript vervang "" door ""

@Mike, controleer het antwoord dat ik daar gaf ... regexp is niet de enige manier om meerdere occurrences van een subsrting te vervangen, verre van dat. Denk flexibel, denk split!

var newText = "the cat looks like a cat".split('cat').join('dog');

Als alternatief, om te voorkomen dat woorddelen worden vervangen - wat het goedgekeurde antwoord ook zal doen! Je kunt dit probleem omzeilen met behulp van reguliere expressies die, ik geef toe, iets ingewikkelder zijn en als een resultaat daarvan ook een beetje langzamer:

var regText = "the cat looks like a cat".replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");

De uitvoer is hetzelfde als het geaccepteerde antwoord, maar gebruikt de expressie / cat / g op deze tekenreeks:

var oops = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/cat/g,'dog');
//returns "the dog looks like a dog, not a dogerpillar or cooldog" ?? 

Oeps, dit is waarschijnlijk niet wat je wilt. Wat is dan? IMHO, een regex die 'kat' alleen voorwaardelijk vervangt. (dus geen onderdeel van een woord), zoals zo:

var caterpillar = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
//return "the dog looks like a dog, not a caterpillar or coolcat"

Mijn gok is dat dit aan jouw behoeften voldoet. Het is natuurlijk niet volledigdicht, maar het zou genoeg moeten zijn om je op weg te helpen. Ik zou aanraden om meer te lezen op deze pagina's. Dit zal van pas komen bij het perfectioneren van deze uitdrukking om aan uw specifieke behoeften te voldoen.

http://www.javascriptkit.com/jsref/regexp.shtml

http://www.regular-expressions.info


Laatste toevoeging:

Gezien deze vraag nog steeds veel meningen krijgt, dacht ik dat ik er een voorbeeld aan zou toevoegen .replace gebruikt met een callback-functie. In dit geval wordt de expressie drastisch vereenvoudigd en biedt nog meer flexibiliteit, zoals het vervangen met correct hoofdlettergebruik of het vervangen van beide cat en cats in een keer:

'Two cats are not 1 Cat! They\'re just cool-cats, you caterpillar'
   .replace(/(^|.\b)(cat)(s?\b.|$)/gi,function(all,char1,cat,char2)
    {
       //check 1st, capitalize if required
       var replacement = (cat.charAt(0) === 'C' ? 'D' : 'd') + 'og';
       if (char1 === ' ' && char2 === 's')
       {//replace plurals, too
           cat = replacement + 's';
       }
       else
       {//do not replace if dashes are matched
           cat = char1 === '-' || char2 === '-' ? cat : replacement;
       }
       return char1 + cat + char2;//return replacement string
    });
//returns:
//Two dogs are not 1 Dog! They're just cool-cats, you caterpillar

75
2018-03-01 10:02



Overeenkomen met een algemene reguliere expressie:

anotherString = someString.replace(/cat/g, 'dog');

45
2018-05-06 23:23



str = str.replace(/abc/g, '');

Of probeer de functie replaceAll vanaf hier:

Wat zijn handige JavaScript-methoden die ingebouwde objecten uitbreiden?

str = str.replaceAll('abc', ''); OR

var search = 'abc';
str = str.replaceAll(search, '');

BEWERK: Verduidelijking over vervangenAlle beschikbaarheid

De 'replaceAll'-methode wordt toegevoegd aan het prototype van String. Dit betekent dat het beschikbaar is voor alle stringobjecten / literals.

Bijv.

var output = "test this".replaceAll('this', 'that');  //output is 'test that'.
output = output.replaceAll('that', 'this'); //output is 'test this'

34
2017-07-17 17:55



Stel dat je alle 'abc' wilt vervangen door 'x':

let some_str = 'abc def def lom abc abc def'.split('abc').join('x')
console.log(some_str) //x def def lom x x def

Ik probeerde na te denken over iets simpels dan het aanpassen van het stringprototype.


29
2017-09-10 14:59



Gebruik een reguliere expressie:

str.replace(/abc/g, '');

27
2017-07-17 17:56