Quelle est la manière efficace de remplacer toutes les occurrences d'un caractère par un autre caractère dans std::string
?
std::string
est un conteneur spécifiquement conçu pour fonctionner avec des séquences de caractères. lien
Quelle est la manière efficace de remplacer toutes les occurrences d'un caractère par un autre caractère dans std::string
?
std::string
est un conteneur spécifiquement conçu pour fonctionner avec des séquences de caractères. lien
Malheureusement, cela permet de remplacer seulement un caractère par un autre caractère. Il ne peut pas remplacer un caractère par plusieurs caractères (c'est-à-dire par une chaîne). Existe-t-il un moyen de faire une recherche-remplacement avec plusieurs caractères?
La question est centrée sur le remplacement de character
, mais, comme j'ai trouvé cette page très utile (surtout le commentaire de Konrad), je voudrais partager cette implémentation plus généralisée, qui permet de traiter aussi des substrings
:
std::string ReplaceAll(std::string str, const std::string& from, const std::string& to) {
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // Gère le cas où 'to' est une sous-chaîne de 'from'
}
return str;
}
Utilisation:
std::cout << ReplaceAll(string("Nombre De Haricots"), std::string(" "), std::string("_")) << std::endl;
std::cout << ReplaceAll(string("ghghjghugtghty"), std::string("gh"), std::string("X")) << std::endl;
std::cout << ReplaceAll(string("ghghjghugtghty"), std::string("gh"), std::string("h")) << std::endl;
Résultats:
Nombre_De_Haricots
XXjXugtXty
hhjhugthty
ÉDITER:
L'approche ci-dessus peut être implémentée de manière plus adaptée, au cas où la performance est une préoccupation, en ne renvoyant rien (void
) et en effectuant les modifications "en place"; c'est-à-dire, en modifiant directement l'argument de chaîne str
, passé par référence au lieu de par valeur. Cela éviterait une copie coûteuse supplémentaire de la chaîne d'origine en l'écrasant.
Code:
static inline void ReplaceAll2(std::string &str, const std::string& from, const std::string& to)
{
// Même code interne...
// Pas de déclaration de retour
}
En espérant que cela sera utile pour d'autres...
Cette fonction présente un problème de performance dans les cas où la chaîne source est grande et où il y a de nombreuses occurrences de la chaîne à remplacer. string::replace() serait appelé de nombreuses fois, ce qui entraîne de nombreuses copies de chaîne. Consultez ma solution qui résout ce problème.
Chipotage à venir : par adresse => par référence. Que ce soit une adresse ou non est un détail d'implémentation.
Je pensais ajouter également la solution boost :
#include
// en place
std::string in_place = "blah#blah";
boost::replace_all(in_place, "#", "@");
// copie
const std::string input = "blah#blah";
std::string output = boost::replace_all_copy(input, "#", "@");
Ensuite, il vous manque quelques drapeaux -I
pour votre compilateur afin qu'il puisse trouver les bibliothèques Boost sur votre système. Peut-être devez-vous même l'installer d'abord.
Une simple recherche et remplacement pour un seul caractère se ferait quelque chose comme suit :
s.replace(s.find("x"), 1, "y")
Pour le faire pour toute la chaîne de caractères, la chose facile à faire serait de boucler jusqu'à ce que votre s.find
commence à renvoyer npos
. Je suppose que vous pourriez également attraper range_error
pour sortir de la boucle, mais c'est plutôt moche.
Tandis que c'est probablement une solution adaptée lorsque le nombre de caractères à remplacer est faible par rapport à la longueur de la chaîne, cela ne s'adapte pas bien. À mesure que la proportion de caractères dans la chaîne d'origine qui doivent être remplacés augmente, cette méthode approchera O(N^2) en temps.
Vrai. Ma philosophie générale est de faire la chose facile (à écrire et à lire) jusqu'à ce que les inefficacités causent de réels problèmes. Il y a des circonstances où vous pourriez avoir des chaînes énormes où O(N**2) compte, mais 99% du temps mes chaînes sont de 1K ou moins.
Comme l'a suggéré Kirill, utilisez la méthode replace ou itérez le long de la chaîne en remplaçant chaque caractère indépendamment.
Alternativement, vous pouvez utiliser la méthode find
ou find_first_of
en fonction de vos besoins. Aucune de ces solutions ne fera le travail en une seule fois, mais avec quelques lignes de code supplémentaires, vous devriez les rendre fonctionnels. :-)
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
0 votes
Il semble que la stdlib est nulle quand il s'agit de telles fonctionnalités "avancées". Il vaut mieux utiliser QString ou une bibliothèque générale lorsque vous commencez à trouver des éléments manquants.