J'ai cette chaîne:
"Test abc test test abc test test test abc test test abc"
Faire:
str = str.replace('abc', '');
semble supprimer uniquement la première occurrence de abc
dans la chaîne ci-dessus.
Comment puis-je en remplacer toutes les occurrences?
javascript
string
replace
Cliquez Upvote
la source
la source
aba
inababa
parca
, quel résultat attendez-vous?caba
?abca
?cca
?String.prototype.replaceAll()
livré dans Safari 13.1 et est maintenant dans Firefox Nightly et Chrome Dev et Canary et sera livré dans Firefox 77 et Chrome 85. Ce n'est pas encore documenté dans MDN, mais github.com/tc39/proposal-string-replaceall#high-level-api a un explicateur: «Si searchValue est une chaîne,String.prototype.replaceAll
remplace toutes les occurrences de searchValue (comme si.split(searchValue).join(replaceValue)
ou une expression régulière globale et correctement échappée avait été utilisée). Si searchValue est une expression régulière non globale,String.prototype.replaceAll
lève une exception »Réponses:
Remarque: Ne l'utilisez pas dans un code critique pour les performances.
Comme alternative aux expressions régulières pour une chaîne littérale simple, vous pouvez utiliser
Le schéma général est
Dans certains cas, cela était plus rapide que l'utilisation
replaceAll
et une expression régulière, mais cela ne semble plus être le cas dans les navigateurs modernes.Indice de référence: https://jsperf.com/replace-all-vs-split-join
Conclusion: si vous avez un cas d'utilisation critique pour les performances (par exemple, le traitement de centaines de chaînes), utilisez la méthode Regexp. Mais pour la plupart des cas d'utilisation typiques, cela vaut la peine de ne pas avoir à se soucier des caractères spéciaux.
la source
String.prototype.replaceAll = function(f,r){return this.split(f).join(r);}
. Utilisation:"My string".replaceAll('st', '');
produit "Mon anneau"replaceAll
fonction, et cela devient tout aussi lisible que toute autre chose. Comme les performances ne sont pas mauvaises, il n'y a aucune raison d'éviter cette solution.En réponse au commentaire:
En réponse au commentaire de Click Upvote , vous pouvez le simplifier encore plus:
Remarque: Les expressions régulières contiennent des caractères (méta) spéciaux, et en tant que tel, il est dangereux de passer aveuglément un argument dans la
find
fonction ci-dessus sans le pré-traiter pour échapper à ces caractères. Ceci est couvert dans le Developer Network Mozilla de JavaScript Guide sur les expressions régulières , où ils présentent la fonction d'utilité suivante (qui a changé au moins deux fois depuis cette réponse a été écrit à l' origine, alors assurez - vous de consulter le site MDN pour les mises à jour possibles):Ainsi, afin de rendre la
replaceAll()
fonction ci-dessus plus sûre, elle pourrait être modifiée comme suit si vous incluez égalementescapeRegExp
:la source
function replaceAll(find, replace,str) { var re = new RegExp(find, 'g'); str = str.replace(re, replace); return str; }
replaceAll
implémentation est qu'elle ne fonctionnera pas sifind
contient des métacaractères.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 général, l'extension des prototypes intégrés en JavaScript n'est généralement pas recommandée. Je fournis des extensions sur le prototype String simplement à des fins d'illustration, montrant différentes implémentations d'une méthode standard hypothétique sur le
String
prototype intégré.Implémentation basée sur l'expression régulière
Implémentation de Split and Join (fonctionnelle)
Ne sachant pas trop comment les expressions régulières fonctionnent en arrière-plan en termes d'efficacité, j'ai eu tendance à pencher vers la séparation et à rejoindre la mise en œuvre dans le passé sans penser aux performances. 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 , l' implémentation de scission et de jointure é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 exécutant ces deux implémentations l'une contre l'autre.
Comme indiqué dans le commentaire ci-dessous par @ThomasLeduc et d'autres, il pourrait y avoir un problème avec l'implémentation basée sur une expression régulière si elle
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 au préalable à la chaîne ou ne transmettra que les chaînes qui ne contiennent pas les caractères du tableau dans les expressions régulières (MDN).MDN fournit également une implémentation pour échapper à nos chaînes. Ce serait bien si cela était également standardisé car
RegExp.escape(str)
, hélas, cela n'existe pas:Nous pourrions appeler
escapeRegExp
dans notreString.prototype.replaceAll
implémentation, 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).la source
L'utilisation d'une expression régulière avec le
g
jeu d'indicateurs remplacera tout:Voir ici aussi
la source
var sourceText
le nombre d'instances (numOfInstances
) en utilisantsubstring
ou diviser et compter la longueur (entre autres stratégies),thatWhichYouWantToReplace
puis fairefor (var i = 0; i < numOfInstances; i++){ sourceText = sourceText.replace('thatWhichYouWantToReplace', '');
} ou encore plus simplement utiliser une boucle while (while sourceText.indexOf(thatWhichYouWantToReplace > -1){ sourceText = sourceText.replace(...)
) mais je ne vois pas pourquoi vous voudriez faire de cette façon lors de l'utilisation/g
est si facile et probablement plus performant.Voici une fonction de prototype de chaîne basée sur la réponse acceptée:
ÉDITER
Si votre
find
contient des caractères spéciaux, vous devez les échapper:Violon: http://jsfiddle.net/cdbzL/
la source
find
contient des caractères comme.
ou$
qui ont des significations spéciales dans l'expression régulière?var str = this
crée une deuxième référence à la chaîne immuable, à laquelle lareplace
méthode est appliquée, qui retourne à son tour une nouvelle chaîne immuable . ces fonctions prototypes renvoient une nouvelle chaîne immuable, sinon, vous seriez en mesure d'écriresomeStrVar.replaceAll('o', '0');
et voussomeStrVar
seriez modifié. Au lieu de cela, vous devez écriresomeStrVar = someStrVar.replaceAll('o', '0');
<- réaffecter pour définir le var pour contenir la nouvelle chaîne immuable . il n'y a aucun moyen de contourner cela. Essayez en console:x = 'foobar'; x.replaceAll('o', '0'); x;
Mise à jour:
Il est un peu tard pour une mise à jour, mais comme je suis juste tombé sur cette question et que j'ai remarqué que ma réponse précédente n'est pas celle dont je suis satisfait. Étant donné que la question impliquait de remplacer un seul mot, il est incroyable que personne n'ait pensé à utiliser les limites des mots (
\b
)Il s'agit d'une expression régulière 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. Les conditions peuvent donc être utilisées dans ce cas pour éviter de remplacer des chaînes commecool-cat
:en gros, cette question est la même que la question ici: Javascript remplace "'" par "' '"
@Mike, vérifiez la réponse que j'ai donnée là-bas ... regexp n'est pas le seul moyen de remplacer plusieurs occurrences d'une souscription, loin de là. Pensez flexible, pensez divisé!
Alternativement, pour éviter de remplacer des parties de mots - 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, en conséquence, un peu plus lentes aussi:
La sortie est la même que la réponse acceptée, cependant, en utilisant l'expression / cat / g sur cette chaîne:
Oups en effet, ce n'est probablement pas ce que vous voulez. Qu'est-ce donc? À mon humble avis, une expression régulière qui ne remplace que «chat» conditionnellement. (c'est-à-dire ne faisant pas partie d'un mot), comme ceci:
Je suppose que cela répond à vos besoins. Ce n'est pas complet, bien sûr, mais cela devrait suffire pour vous aider à démarrer. Je recommanderais de lire un peu plus sur ces pages. Cela s'avérera utile pour perfectionner 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 obtient toujours beaucoup de vues, j'ai pensé que je pourrais ajouter un exemple d'
.replace
utilisation avec une fonction de rappel. Dans ce cas, il simplifie considérablement l'expression et offre encore plus de flexibilité, comme le remplacement par une capitalisation correcte ou le remplacement des deuxcat
etcats
en une seule fois:la source
Correspondance avec une expression régulière globale:
la source
Pour remplacer une utilisation unique:
Pour remplacer plusieurs fois, utilisez:
la source
replace(/\n/g, '<br/>')
Ce sont les méthodes les plus courantes et les plus lisibles.
Méthode 1:
Méthode 2:
Méthode 3:
Méthode 4:
Production:
la source
Ou essayez la fonction replaceAll à partir d'ici:
Quelles sont les méthodes JavaScript utiles qui étendent les objets intégrés?
EDIT: Clarification sur le remplacementToute disponibilité
La méthode 'replaceAll' est ajoutée au prototype de String. Cela signifie qu'il sera disponible pour tous les objets chaîne / littéraux.
Par exemple
la source
Utiliser
RegExp
en JavaScript pourrait faire le travail pour vous, faites simplement quelque chose comme le code ci-dessous, n'oubliez pas ce/g
qui se démarque pour global :Si vous pensez à réutiliser, créez une fonction pour le faire pour vous, mais ce n'est pas recommandé car ce n'est qu'une fonction de ligne, mais encore une fois si vous l'utilisez fortement, vous pouvez écrire quelque chose comme ceci:
et utilisez-le simplement dans votre code encore et encore comme ci-dessous:
Mais comme je l'ai mentionné plus tôt, cela ne fera pas une énorme 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 également une bonne pratique du code DRY si vous souhaitez réutiliser.
la source
Supposons que vous souhaitiez remplacer tous les 'abc' par 'x':
J'essayais de penser à quelque chose de plus simple que de modifier le prototype de chaîne.
la source
Utilisez une expression régulière:
la source
Remplacement des guillemets simples:
la source
// boucle jusqu'à ce que le nombre d'occurrences atteigne 0. OU simplement copier / coller
la source
.indexOf
dans une variable et utilisez cette variable comme deuxième paramètre de.indexOf
(moins la longueur du mot-clé, plus la longueur de la chaîne de remplacement).a mieux fonctionné pour moi que les réponses ci-dessus.
new RegExp("abc", 'g')
crée donc un RegExp qui correspond à toutes les occurrences ('g'
flag) du texte ("abc"
). La deuxième partie est ce qui est remplacé, dans votre cas, une chaîne vide (""
).str
est la chaîne, et nous devons la remplacer, carreplace(...)
renvoie simplement le résultat, mais pas les substitutions. Dans certains cas, vous voudrez peut-être l'utiliser.la source
Il s'agit de la version la plus rapide qui n'utilise pas d'expressions régulières .
Jsperf révisé
Il est presque deux fois plus rapide que la méthode de fractionnement et de jointure.
Comme indiqué dans un commentaire ici, cela ne fonctionnera pas si votre
omit
variable contientplace
, 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 vont encore plus vite ( http://jsperf.com/replace-all-vs-split-join/12 )!
la source
if(place.replace(omit) === omit) {
Aucune correspondance, il est donc sûr d'utiliser remplacer la boucle} else {
Correspondance, utilisez donc une méthode différente comme le fractionnement et la jointure}
Performance
Aujourd'hui 27.12.2019 j'effectue des tests sur macOS v10.13.6 (High Sierra) pour les solutions choisies.
Conclusions
str.replace(/abc/g, '');
( C ) est une bonne solution rapide multi-navigateur pour toutes les chaînes.split-join
( A, B ) oureplace
( C, D ) sont rapideswhile
( E, F, G, H ) sont lentes - généralement ~ 4 fois plus lentes pour les petites cordes et environ ~ 3000 fois (!) Plus lentes pour les longues cordesJe crée également ma propre solution. Il semble que ce soit actuellement le plus court qui fasse le travail de question:
Afficher l'extrait de code
Détails
Les tests ont été effectués sur Chrome 79.0, Safari 13.0.4 et Firefox 71.0 (64 bits). Les tests
RA
et l'RB
utilisation de la récursivité. RésultatsChaîne courte - 55 caractères
Vous pouvez exécuter des tests sur votre machine ICI . Résultats pour Chrome:
Chaîne longue: 275 000 caractères
Les solutions récursives RA et RB donnent
Pour 1 million de personnages, ils cassent même Chrome
J'essaie d'effectuer des tests pour 1M de caractères pour d'autres solutions, mais E, F, G, H prennent tellement de temps que le navigateur me demande de casser le script, donc je réduit la chaîne de test à 275K caractères. Vous pouvez exécuter des tests sur votre machine ICI . Résultats pour Chrome
Code utilisé dans les tests
Afficher l'extrait de code
la source
Si ce que vous voulez trouver est déjà dans une chaîne et que vous n'avez pas d'escape regex à portée de main, vous pouvez utiliser join / split:
la source
la source
J'aime cette méthode (elle a l'air un peu plus propre):
la source
Le moyen le plus simple de le faire sans utiliser aucune expression régulière est de fractionner et de rejoindre comme le code ici:
la source
http://jsfiddle.net/ANHR9/
la source
la source
Si la chaîne contient un modèle similaire
abccc
, vous pouvez utiliser ceci:la source
Les réponses précédentes sont beaucoup trop compliquées. Utilisez simplement la fonction de remplacement comme ceci:
Exemple:
la source
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:
Une fois terminé, vous aurez toujours «test abc»!
La boucle la plus simple pour résoudre ce problème serait:
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:
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é, l'expression régulière devient complexe et suffisamment lente pour boucler à la place.]
la source
Bien que les gens aient mentionné l'utilisation de l'expression rationnelle, il existe une meilleure approche si vous souhaitez remplacer le texte indépendamment de la casse du texte. Comme majuscule ou minuscule. Utilisez la syntaxe ci-dessous
Vous pouvez vous référer à l'exemple détaillé ici .
la source
Vous pouvez simplement utiliser la méthode ci-dessous
la source
Ajoutez simplement
/g
à
/g
signifie globalla source