spéciaux - supprimer un caractère d'une chaine javascript




Comment remplacer toutes les occurrences d'une chaîne en JavaScript? (20)

// boucle 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;
    }

J'ai cette ficelle:

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

Faire

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

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


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

Jsperf révisé

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 plus rapide que la méthode split et join.

Comme indiqué dans un commentaire ici, cela ne fonctionnera pas si votre variable omit contient place , comme dans: replaceAll("string", "s", "ss") , car elle pourra toujours remplacer une autre occurrence du mot. .

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

  • Mise à jour du 27 juillet 2017: Il semblerait que RegExp présente désormais les performances les plus rapides de la récente version de Chrome 59.

Il suffit de suivre cette expression rationnelle oneliner en ajoutant la sensibilité à la casse, donc si vous faites "ABC", il agira de la même manière que celui de "abc".

str = str.replace(/abc/gi, "");

J'aime cette méthode (elle a l'air un peu plus propre):

text = text.replace(new RegExp("cat","g"), "dog"); 

Par souci d'exhaustivité, j'ai réfléchi à la méthode à utiliser pour ce faire. Il existe essentiellement deux façons de procéder, comme le suggèrent les autres réponses de cette page.

Remarque: En règle générale, il n'est pas recommandé d'étendre les prototypes intégrés en JavaScript. Je fournis des extensions sur le prototype String simplement à des fins d’illustration, illustrant différentes implémentations d’une méthode standard hypothétique sur le prototype intégré String .

Implémentation basée sur une expression régulière

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

Mise en œuvre fractionnée et jointe (fonctionnelle)

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

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

Sur mon ordinateur Windows 8 Chrome, l’implémentation basée sur une expression régulière est la plus rapide , l’ implémentation des jointures et des scans étant 53% plus lente . Cela signifie que les expressions régulières sont deux fois plus rapides pour l’entrée lorem ipsum que j’ai utilisée.

Découvrez ce benchmark d' benchmark comparant ces deux implémentations.

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

MDN fournit également une implémentation pour échapper à nos chaînes. Ce serait bien si cela était aussi standardisé sous RegExp.escape(str) , mais hélas, ça n'existe pas:

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

Nous pourrions appeler escapeRegExp dans notre implémentation String.prototype.replaceAll . Cependant, je ne sais pas dans quelle mesure cela affectera les performances (potentiellement même pour les chaînes pour lesquelles l'échappement n'est pas nécessaire, comme toutes les chaînes alphanumériques).


Remplacer les guillemets simples:

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

    return text;
}

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

str.replace(/abc(\s|$)/g, "")

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 problème serait:

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

Mais cela exécute le remplacement deux fois pour chaque cycle. Peut-être (au risque d’être rejeté) qui peut être combiné pour une 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 vous recherchez des chaînes en double.
Par exemple, si nous avons 'a ,,, b' et que nous souhaitons supprimer toutes les virgules en double.
[Dans ce cas, on pourrait faire .replace (/, + / g, ','), mais à un moment donné, la regex devient assez complexe et lente pour faire une boucle.]


Utiliser RegExp en JavaScript pourrait faire le travail pour vous, faites simplement quelque chose comme ci-dessous:

var str = "ff ff f f a de def";
str = str.replace(/f/g,'');
alert(str);

Si vous envisagez de réutiliser, créez une fonction pour le faire à votre place, mais ce n'est pas recommandé car ce n'est qu'une fonction à une ligne, mais encore une fois, si vous utilisez énormément cela, vous pouvez écrire quelque chose comme ceci:

while (str.indexOf('abc') !== -1)
{
    str = str.replace('abc', '');
}

et utilisez-le simplement dans votre code, encore et encore, comme ci-dessous:

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

Mais comme je l’ai mentionné précédemment, 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 accélérer les performances sur les chaînes longues et constituer une bonne pratique de code DRY si vous souhaitez les réutiliser.


Utilisez une expression régulière:

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

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);
};

Mettre à jour:

Il est un peu tard pour une mise à jour, mais depuis que je suis tombé sur cette question et que j'ai remarqué que ma réponse précédente ne me plaisait pas. Puisque la question impliquait de remplacer un seul mot, il est incroyable que personne n'ait pensé à utiliser les limites de mots ( \b )

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

C'est un regex simple qui évite de remplacer des parties de mots dans la plupart des cas. Cependant, un tiret - est toujours considéré comme une limite de mot. Donc, les conditionnels peuvent être utilisés dans ce cas pour éviter de remplacer des chaînes 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,'$1dog$2');
//"a dog is not a cool-cat"

fondamentalement, cette question est la même que la question ici: Javascript remplace "" "avec" ""

@ Mike, vérifie la réponse que j'ai donnée là-bas ... l'expression rationnelle n'est pas le seul moyen de remplacer plusieurs occurrences d'une souscription, loin de là. Pensez flexible, pensez à diviser!

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

Sinon, pour éviter de remplacer des parties verbales - ce que 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, par conséquent, un peu plus lentes:

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

La sortie est identique à la réponse acceptée, toutefois, en utilisant l'expression / cat / g sur cette chaîne:

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

Oups en effet, ce n'est probablement pas ce que vous voulez. Qu'est-ce que c'est alors? IMHO, une regex qui ne remplace que "chat" de manière conditionnelle. (c.-à-d. ne faisant pas partie d'un mot), comme suit:

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"

À mon avis, cela répond à vos besoins. Ce n'est pas complet, bien sûr, mais cela devrait suffire à vous aider à démarrer. Je recommande de lire un peu plus sur ces pages. Cela s'avérera utile pour perfectionner cette expression afin de 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 .replace encore de nombreux points de vue, j'ai pensé ajouter un exemple d' .replace de .replace avec une fonction de rappel. Dans ce cas, cela simplifie considérablement l'expression et offre encore plus de flexibilité, comme le remplacement par une capitalisation correcte ou le remplacement simultané du cat et des cats :

'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

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 signifie global


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");

Il vous suffit de copier et coller ce code dans la console de votre navigateur pour tester.


Bien que certaines personnes aient mentionné l’utilisation de regex, il existe une meilleure approche si vous souhaitez remplacer le texte, quel que soit le cas. Comme en majuscule ou en minuscule. Utilisez 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é here .


J'utilise p pour stocker le résultat du remplacement précédent de la récursivité:

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 que cela soit possible:

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

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

replaceAll('abbbbb', 'a', 'ab') → 'abbbbb'

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

http://jsfiddle.net/ANHR9/


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;
}

str = str.replace(new RegExp("abc", 'g'), "");

a fonctionné mieux pour moi que les réponses ci-dessus. so new RegExp("abc", 'g') crée une RegExp qui correspond à toutes les occurrences (indicateur 'g' ) du texte ( "abc" ). La deuxième partie est ce qui est remplacé par, dans votre cas, une chaîne vide ( "" ). str est la chaîne, et nous devons la remplacer, car replace(...) ne renvoie que le résultat, mais pas la substitution. Dans certains cas, vous voudrez peut-être utiliser cela.


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




replace