Comment remplacer toutes les occurrences D'une chaîne dans JavaScript?

j'ai cette chaîne:

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

Faire

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

semble supprimer seulement la première occurrence de abc dans la chaîne ci-dessus. Comment puis-je remplacer tous les occurrences de celui-ci?

3311
demandé sur Lamy 2009-07-17 21:53:46

30 réponses

par souci d'exhaustivité, j'ai réfléchi à la méthode que je devais utiliser pour le faire. Il existe essentiellement deux façons de le faire, comme suggéré par les autres réponses sur cette page.

Note: en général, il n'est pas recommandé d'étendre les prototypes intégrés dans JavaScript. Je fournis comme extensions sur le prototype de chaîne de caractères simplement à des fins d'illustration, montrant différentes implémentations d'une norme hypothétique méthode sur le prototype incorporé String .


Expression Régulière En Fonction De La Mise En Œuvre

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

Split et Join (Fonctionnelle) de la mise en Œuvre

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

" sans trop savoir comment les expressions régulières fonctionnent en coulisse en termes d'efficacité, j'ai eu tendance à pencher vers la scission et à rejoindre la mise en œuvre dans le passé sans penser à performance. Quand je me suis demandé ce qui était le plus efficace, et par quelle marge, Je l'ai utilisé comme excuse pour le découvrir.

sur ma machine Chrome Windows 8, l'implémentation basée sur l'expression régulière est la plus rapide , avec la split and join implementation étant 53% plus lente . Ce qui signifie que les expressions régulières sont deux fois plus rapides pour l'entrée ipsum lorem que j'ai utilisé.

Regardez ce benchmark lancer ces deux implémentations l'une contre l'autre.


comme indiqué dans le commentaire ci-dessous de @ThomasLeduc et d'autres, il pourrait y avoir un problème avec la mise en œuvre basée sur les expressions régulières si search contient certains caractères qui sont réservés comme caractères spéciaux dans les expressions régulières . La mise en œuvre suppose que l'appelant échappera à la chaîne au préalable ou ne passera que les chaînes qui sont sans les caractères dans la table expressions régulières (MDN).

MDN fournit également une implémentation pour échapper à nos chaînes. Il serait bien que ce soit aussi standardisé comme RegExp.escape(str) , mais hélas, il n'existe pas:

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

nous pourrions appeler escapeRegExp dans le cadre de notre implémentation String.prototype.replaceAll , cependant, je ne suis pas sûr que cela affectera la performance (potentiellement même pour les chaînes pour lesquelles l'escape n'est pas nécessaire, comme toutes les chaînes alphanumériques).

1752
répondu Cory Gross 2017-05-27 21:55:56
str = str.replace(/abc/g, '');

en réponse au commentaire:

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

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

en réponse au commentaire de cliquez sur Upvote , vous pouvez le simplifier encore plus:

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

Note: les expressions régulières contiennent des caractères (meta) spéciaux, et en tant que tel il est dangereux de passer aveuglément un argument dans la fonction find ci-dessus sans le pré-traiter pour échapper à ces caractères. Ceci est couvert dans l' Mozilla Developer Network 's JavaScript Guide on Regular Expressions , où ils présentent la fonction utilitaire suivante:

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

afin de rendre plus sûre la fonction replaceAll() ci-dessus, elle pourrait être modifiée comme suit si vous incluez aussi escapeRegExp :

function replaceAll(str, find, replace) {
    return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
3686
répondu Sean Bright 2017-06-21 22:17:14

Note: Ne l'utilisez pas en code réel.

comme alternative aux expressions régulières pour une simple chaîne littérale, vous pouvez utiliser

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

le schéma général est

str.split(search).join(replacement)

cela était plus rapide dans certains cas que d'utiliser replaceAll et une expression régulière, mais cela ne semble plus être le cas dans les navigateurs modernes. Donc, ça ne devrait vraiment être utilisé que comme un piratage rapide pour éviter d'avoir à échapper à l'expression régulière, pas dans le code réel.

1207
répondu Matthew Crumley 2017-01-24 14:38:59

utilisant une expression régulière avec le drapeau g remplacera tout:

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

voir ici aussi

519
répondu Adam A 2016-05-17 12:15:25

Voici une fonction de prototype de chaîne basée sur la réponse acceptée:

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

MODIFIER

si votre find contient des caractères spéciaux, alors vous devez les éviter:

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

violon: http://jsfiddle.net/cdbzL /

92
répondu jesal 2013-10-07 16:40:16

mise à jour:

il est un peu tard pour une mise à jour, mais puisque je viens de tomber sur cette question, et ai remarqué que ma réponse précédente n'est pas une que je suis heureux avec. Puisque la question consistait à remplacer un seul mot, c'est incroyable que personne n'ait pensé à utiliser des limites de mots ( \b )

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

il s'agit d'un simple regex qui évite de remplacer des parties de mots dans la plupart des cas. Cependant, un tiret - est toujours considéré comme une limite de mots. Ainsi, les conditionnels peuvent être utilisés dans ce cas pour éviter de remplacer des cordes comme 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,'dog');
//"a dog is not a cool-cat"

fondamentalement, cette question Est la même que la question ici: JavaScript remplacer "'" par "

@Mike, vérifiez la réponse que j'ai donné là... regexp n'est pas le seul moyen de remplacer les multiples occurrences d'un subsrting, far à partir d'elle. Pense flexible, pense split!

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

alternativement, pour éviter de remplacer des parties de mot-qui la réponse approuvée fera aussi! Vous pouvez contourner ce problème en utilisant des expressions régulières qui sont, je l'admets, un peu plus complexes et en conséquence, un peu plus lente, aussi:

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

la sortie est la même que la réponse acceptée, cependant, en utilisant l'expression/cat / G sur cette chaîne de caractères:

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" ?? 

en effet, ce n'est probablement pas ce que vous voulez. Quelle est, alors? IMHO, un regex qui ne remplace " cat " que conditionnellement. (ne fait pas partie d'un mot), comme ainsi:

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

je pense que ça répond à vos besoins. Ce n'est pas infaillible, bien sûr, mais ça devrait suffire pour commencer. Je recommande d'en lire plus sur ces pages. Cela s'avérera utile pour parfaire cette expression pour répondre à vos besoins spécifiques.

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

http://www.regular-expressions.info


ajout Final:

étant donné que cette question reçoit encore beaucoup de points de vue, j'ai pensé que je pourrais ajouter un exemple de .replace utilisé avec une fonction de rappel. Dans ce cas, il simplifie considérablement l'expression et offre encore plus de flexibilité, comme remplacer par une capitalisation correcte ou remplacer à la fois cat et cats en une seule fois:

'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
répondu Elias Van Ootegem 2017-05-23 11:47:36

Match contre une expression régulière globale:

anotherString = someString.replace(/cat/g, 'dog');
51
répondu scronide 2009-05-06 23:23:40
str = str.replace(/abc/g, '');

ou essayez la fonction replaceAll à partir de là:

quelles sont les méthodes JavaScript utiles qui étendent les objets intégrés?

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

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

EDIT: Clarification sur la disponibilité de remplacement

la méthode "replaceAll" est ajoutée au prototype de String. Cela signifie qu'il sera disponible pour tous les objets string/littéraux.

E. G.

var output = "test this".replaceAll('this', 'that');  //output is 'test that'.
output = output.replaceAll('that', 'this'); //output is 'test this'
35
répondu SolutionYogi 2017-05-23 12:34:57

dites que vous voulez remplacer tous les 'abc' par '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

j'essayais de penser à quelque chose de plus simple que de modifier le prototype de chaîne.

30
répondu Emilio Grisolía 2017-05-27 22:01:59

utiliser une expression régulière:

str.replace(/abc/g, '');
27
répondu Donnie DeBoer 2017-05-27 21:56:32

remplaçant les guillemets simples:

function JavaScriptEncode(text){
    text = text.replace(/'/g,''')
    // More encode here if required

    return text;
}
25
répondu Chris OnDaRocks 2017-12-17 15:53:28

//bouclez-le jusqu'à ce que le nombre d'occurrences atteigne 0. Ou simplement copier/coller

    function replaceAll(find, replace, str) 
    {
      while( str.indexOf(find) > -1)
      {
        str = str.replace(find, replace);
      }
      return str;
    }
22
répondu Raseela 2013-09-05 14:01:12

C'est la version la plus rapide que n'utilise pas les expressions régulières .

révisé jsperf

replaceAll = function(string, omit, place, prevstring) {
  if (prevstring && string === prevstring)
    return string;
  prevstring = string.replace(omit, place);
  return replaceAll(prevstring, omit, place, string)
}

il est presque deux fois aussi rapide que la méthode de fente et de jointure.

comme indiqué dans un commentaire ici, cela ne fonctionnera pas si votre variable omit contient place , comme dans: replaceAll("string", "s", "ss") , parce qu'il sera toujours en mesure de remplacer un autre occurrence du mot.

il y a un autre jsperf avec des variantes sur mon remplacement récursif qui vont encore plus vite ( http://jsperf.com/replace-all-vs-split-join/12 )!

  • mise à jour du 27 juillet 2017: il semble que RegExp ait maintenant la performance la plus rapide dans le Chrome 59 récemment publié.
20
répondu Cole Lawrence 2017-07-27 15:57:56
str = str.replace(new RegExp("abc", 'g'), "");

a fonctionné mieux pour moi que les réponses ci-dessus. ainsi new RegExp("abc", 'g') crée un RegExp ce qui correspond à toute occurrence (drapeau 'g' ) du texte ( "abc" ). La deuxième partie est celle qui est remplacée par, dans votre cas, une chaîne vide ( "" ). str est la chaîne, et nous devons la surcharger, car replace(...) renvoie juste le résultat, mais pas les dérogations. Dans certains cas, vous voudrez l'utiliser.

19
répondu csomakk 2017-12-29 17:52:40
function replaceAll(str, find, replace) {
  var i = str.indexOf(find);
  if (i > -1){
    str = str.replace(find, replace); 
    i = i + replace.length;
    var st2 = str.substring(i);
    if(st2.indexOf(find) > -1){
      str = str.substring(0,i) + replaceAll(st2, find, replace);
    }       
  }
  return str;
}
15
répondu Tim Rivoli 2014-09-29 19:17:45

si ce que vous voulez trouver est déjà dans une chaîne, et que vous n'avez pas d'escaper regex à portée de main, vous pouvez utiliser join / split:

    function replaceMulti(haystack, needle, replacement)
    {
        return haystack.split(needle).join(replacement);
    }

    someString = 'the cat looks like a cat';
    console.log(replaceMulti(someString, 'cat', 'dog'));
14
répondu rakslice 2018-07-23 17:42:33
var str = "ff ff f f a de def";
str = str.replace(/f/g,'');
alert(str);

http://jsfiddle.net/ANHR9 /

12
répondu pkdkk 2013-09-04 10:01:17
while (str.indexOf('abc') !== -1)
{
    str = str.replace('abc', '');
}
12
répondu zdennis 2014-04-29 10:25:12

en utilisant RegExp en JavaScript pourrait faire le travail pour vous, juste faire quelque chose comme ci-dessous:

var str ="Test abc test test abc test test test abc test test abc";
str = str.replace(/abc/g, '');

si vous pensez à réutiliser, créez une fonction pour le faire pour vous, mais ce n'est pas recommandé car c'est seulement une fonction de ligne, mais encore une fois si vous obtenez largement l'utilisation de ceci, vous pouvez écrire quelque chose comme ceci:

String.prototype.replaceAll = String.prototype.replaceAll || function(string, replaced) {
  return this.replace(new RegExp(string, 'g'), replaced);
};

et il suffit de l'utiliser dans votre code comme ci-dessous:

var str ="Test abc test test abc test test test abc test test abc";
str = str.replaceAll('abc', '');

mais comme je l'ai mentionné plus tôt, cela ne fera pas une grande différence en termes de lignes à écrire ou de performances, seule la mise en cache de la fonction peut affecter des performances plus rapides sur les longues chaînes et aussi une bonne pratique de code sec si vous voulez réutiliser.

11
répondu Alireza 2018-07-12 05:57:29

j'aime cette méthode (elle semble un peu plus propre):

text = text.replace(new RegExp("cat","g"), "dog"); 
10
répondu Owen 2017-05-27 21:57:29

Si la chaîne contient un motif similaire comme abccc , vous pouvez utiliser ceci:

str.replace(/abc(\s|$)/g, "")
10
répondu mostafa elmadany 2018-04-27 08:49:49

si vous essayez de vous assurer que la chaîne que vous recherchez n'existera pas même après le remplacement, vous devez utiliser une boucle.

par exemple:

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

une fois terminé, vous aurez toujours 'test abc'!

la boucle la plus simple pour résoudre ce serait:

var str = 'test aabcbc';
while (str != str.replace(/abc/g, '')){
   str.replace(/abc/g, '');
}

mais qui exécute le remplacement deux fois pour chaque cycle. Peut-être (au risque d'être rejeté) qui peuvent être combinées pour un forme légèrement plus efficace mais moins lisible:

var str = 'test aabcbc';
while (str != (str = str.replace(/abc/g, ''))){}
// alert(str); alerts 'test '!

cela peut être particulièrement utile lorsque l'on recherche des chaînes dupliquées.

Par exemple, si nous avons 'a,,, b' et que nous souhaitons supprimer toutes les guillemets en double.

[Dans ce cas, on pourrait le faire .remplacer ( / ,+ / g,','), mais à un moment donné le regex devient complexe et assez lent pour boucler à la place.]

9
répondu SamGoody 2014-09-28 19:58:42
var string  = 'Test abc Test abc Test abc Test abc'
string = string.replace(/abc/g, '')
console.log(string)
9
répondu Ashutosh Narang 2018-03-09 09:41:05

vous pourriez essayer de combiner ces deux méthodes puissantes.

"test abc test test abc".split("abc").join("")

Espère que cela aide!

7
répondu Victor 2013-10-09 15:04:23

vous pouvez simplement utiliser la méthode ci-dessous

/**
 * Replace all the occerencess of $find by $replace in $originalString
 * @param  {originalString} input - Raw string.
 * @param  {find} input - Target key word or regex that need to be replaced.
 * @param  {replace} input - Replacement key word
 * @return {String}       Output string
 */
function replaceAll(originalString, find, replace) {
  return originalString.replace(new RegExp(find, 'g'), replace);
};
7
répondu tk_ 2016-02-23 03:47:11

bien que les gens aient mentionné l'utilisation de regex mais il y a une meilleure approche si vous voulez remplacer le texte indépendamment du cas du texte. Comme en majuscules ou en minuscules. Utiliser la syntaxe ci-dessous

//Consider below example
originalString.replace(/stringToBeReplaced/gi, '');

//Output will be all the occurrences removed irrespective of casing.

vous pouvez vous référer à l'exemple détaillé ici .

7
répondu Cheezy Code 2016-06-08 18:51:40

il suffit de suivre cette oneliner regex ajouter la sensibilité au cas, donc si vous faites" ABC", il agirait le même que celui pour"abc".

str = str.replace(/abc/gi, "");
7
répondu Ankit 2018-09-17 12:58:22

il suffit d'ajouter /g

document.body.innerHTML = document.body.innerHTML.replace('hello', 'hi');

à

// Replace 'hello' string with /hello/g regular expression.
document.body.innerHTML = document.body.innerHTML.replace(/hello/g, 'hi');

/g global

6
répondu Reza Fahmi 2015-10-15 12:13:18

la fonction suivante fonctionne pour moi:

String.prototype.replaceAllOccurence = function(str1, str2, ignore) 
{
    return this.replace(new RegExp(str1.replace(/([\/\,\!\\^$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\$&"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/$/g,"$$$$"):str2);
} ;

appelez maintenant les fonctions comme ceci:

"you could be a Project Manager someday, if you work like this.".replaceAllOccurence ("you", "I");

copiez et collez simplement ce code dans la console de votre navigateur pour le tester.

6
répondu Sandeep Gantait 2016-02-16 09:53:06

j'utilise p pour stocker le résultat de la précédente, la récursivité de remplacement:

function replaceAll(s, m, r, p) {
    return s === p || r.contains(m) ? s : replaceAll(s.replace(m, r), m, r, s);
}

il remplacera toutes les occurrences dans la chaîne s jusqu'à ce qu'il soit possible:

replaceAll('abbbbb', 'ab', 'a') → 'abbbb' → 'abbb' → 'abb' → 'ab' → 'a'

pour éviter boucle infinie je vérifie si le remplacement r contient une correspondance m :

replaceAll('abbbbb', 'a', 'ab') → 'abbbbb'
5
répondu Termininja 2017-02-25 05:45:24