Quelle est la manière efficace de remplacer toutes les occurrences d'un personnage par un autre personnage dans std::string
?
480
Quelle est la manière efficace de remplacer toutes les occurrences d'un personnage par un autre personnage dans std::string
?
std::string
ne contient pas une telle fonction mais vous pouvez utiliser une replace
fonction autonome depuis l'en- algorithm
tête.
#include <algorithm>
#include <string>
void some_func() {
std::string s = "example string";
std::replace( s.begin(), s.end(), 'x', 'y'); // replace all 'x' to 'y'
}
std::string
est un conteneur spécialement conçu pour fonctionner avec des séquences de caractères. lienstd::string::replace()
au lieu destd::replace()
! 'x' (char
) est implicitement casté ensize_t
[valeur 120], ainsi la chaîne entière ou une partie de celle-ci sera remplie avec 120 copies de 'y'.Je pensais que je jetterais aussi la solution boost :
la source
-I
indicateurs pour votre compilateur afin qu'il trouve les bibliothèques Boost sur votre système. Vous devrez peut-être même l'installer d'abord.La question est centrée sur le
character
remplacement, mais, comme j'ai trouvé cette page très utile (surtout la remarque de Konrad ), je voudrais partager cette implémentation plus généralisée, qui permet de traitersubstrings
également:Usage:
Les sorties:
ÉDITER:
Ce qui précède peut être implémenté de manière plus appropriée, au cas où les performances vous intéressent, en ne retournant rien (
void
) et en effectuant les changements directement sur la chaînestr
donnée en argument, passée par adresse au lieu de par valeur . Cela éviterait une copie inutile et coûteuse de la chaîne d'origine, tout en renvoyant le résultat. Votre appel, alors ...Code:
J'espère que cela sera utile pour d'autres ...
la source
from
chaîne est vide, sinon une boucle sans fin se produira.Imaginez un gros objet binaire où tous les octets 0x00 doivent être remplacés par "\ 1 \ x30" et tous les octets 0x01 par "\ 1 \ x31" car le protocole de transport n'autorise aucun \ 0 octet.
Dans les cas où:
les solutions fournies ne peuvent pas être appliquées (car elles ne remplacent que des caractères uniques) ou ont un problème de performances, car elles appellent plusieurs fois string :: replace, ce qui génère des copies de la taille du blob encore et encore. (Je ne connais pas la solution boost, peut-être que c'est OK de ce point de vue)
Celui-ci parcourt toutes les occurrences de la chaîne source et construit la nouvelle chaîne pièce par pièce une fois :
la source
Une simple recherche et remplacement pour un seul caractère aurait quelque chose comme:
s.replace(s.find("x"), 1, "y")
Pour ce faire, pour la chaîne entière, la chose la plus simple serait de boucler jusqu'à ce que vous
s.find
commenciez à revenirnpos
. Je suppose que vous pouvez également attraperrange_error
pour quitter la boucle, mais c'est un peu moche.la source
{
personnage. Je ne sais pas ce qu'est une "double accolade". Vous avez peut-être un problème de police?Si vous cherchez à remplacer plus d'un seul caractère, et que vous ne traitez qu'avec
std::string
, cet extrait fonctionnerait, remplaçant sNeedle dans sHaystack par sReplace, et sNeedle et sReplace n'ont pas besoin d'être de la même taille. Cette routine utilise la boucle while pour remplacer toutes les occurrences, plutôt que la première trouvée de gauche à droite.la source
find
appel deux fois. Pensez à faire de ce résultat une variable temporaire.Comme l'a suggéré Kirill, utilisez la méthode replace ou parcourez la chaîne en remplaçant chaque caractère indépendamment.
Alternativement, vous pouvez utiliser la
find
méthode oufind_first_of
selon ce que vous devez faire. Aucune de ces solutions ne fera l'affaire en une seule fois, mais avec quelques lignes de code supplémentaires, vous devriez les faire fonctionner pour vous. :-)la source
la source
word
est long, il peut y avoir beaucoup de surcharge lors de l'appel de la fonction. Vous pouvez optimiser cela en passantword
,target
etreplacement
comme références de const.Et Abseil StrReplaceAll ? Depuis le fichier d'en-tête:
la source
Vieille école :-)
Résultat:
la source
Cela marche! J'ai utilisé quelque chose de similaire à cela pour une application de librairie, où l'inventaire était stocké dans un fichier CSV (comme un fichier .dat). Mais dans le cas d'un seul caractère, ce qui signifie que le remplaçant n'est qu'un seul caractère, par exemple '|', il doit être entre guillemets "|" afin de ne pas lancer un caractère de conversion non valide.
De façon inhabituelle, j'utilise actuellement CentOS, donc ma version du compilateur est ci-dessous. La version C ++ (g ++), C ++ 98 par défaut:
la source
Si vous êtes prêt à utiliser
std::string
s, vous pouvez utiliser la fonction de cet exemple d'applicationstrsub
telle quelle ou la mettre à jour si vous souhaitez qu'elle prenne un type ou un ensemble de paramètres différent pour atteindre à peu près le même objectif. Fondamentalement, il utilise les propriétés et fonctionnalités destd::string
pour effacer rapidement le jeu de caractères correspondant et insérer les caractères souhaités directement dans lestd::string
. Chaque fois qu'il effectue cette opération de remplacement, l'offset est mis à jour s'il peut toujours trouver les caractères correspondants à remplacer, et s'il ne peut plus rien remplacer, il renvoie la chaîne dans son état depuis la dernière mise à jour.Si vous ne voulez pas compter sur l'utilisation de
std::string
s comme paramètres pour pouvoir passer des chaînes de style C à la place, vous pouvez voir l'exemple mis à jour ci-dessous:la source
Pour les situations simples, cela fonctionne assez bien sans utiliser d'autre bibliothèque que std :: string (qui est déjà utilisée).
Remplacez toutes les occurrences du caractère a par le caractère b dans some_string :
Si la chaîne est volumineuse ou si plusieurs appels à remplacer sont un problème, vous pouvez appliquer la technique mentionnée dans cette réponse: https://stackoverflow.com/a/29752943/3622300
la source
voici une solution que j'ai roulée, dans un esprit DRI maximal. il recherchera sNeedle dans sHaystack et le remplacera par sReplace, nTimes si non 0, sinon toutes les occurrences de sNeedle. il ne cherchera pas à nouveau dans le texte remplacé.
la source