Je veux remplacer , dans un string, une chaîne par une autre. Je
recherche la solution la plus simple et la plus claire (pas
spécialement la plus optimisée).
Pour l'instant je fais comme ceci :
------------------------------------------------------------
int pos = str.length();
while ((pos = str.rfind(from,pos)) != string::npos) {
str.replace( pos // position
,from.length() // taille
,to // Chaine de remplacement
);
}
------------------------------------------------------------
Voyez-vous une façon plus simple et plus courte de faire ?
(c'est pour montrer à mon CP que C++ est un language simple et
performant ;-) )
Je veux remplacer , dans un string, une chaîne par une autre. Je recherche la solution la plus simple et la plus claire (pas spécialement la plus optimisée).
Pour l'instant je fais comme ceci : ------------------------------------------------------------ int pos = str.length();
while ((pos = str.rfind(from,pos)) != string::npos) { str.replace( pos // position ,from.length() // taille ,to // Chaine de remplacement ); } ------------------------------------------------------------
Voyez-vous une façon plus simple et plus courte de faire ? (c'est pour montrer à mon CP que C++ est un language simple et performant ;-) )
Pourquoi rfind au lieu de find ?
David
Bonjour,
Je veux remplacer , dans un string, une chaîne par une autre. Je
recherche la solution la plus simple et la plus claire (pas
spécialement la plus optimisée).
Pour l'instant je fais comme ceci :
------------------------------------------------------------
int pos = str.length();
while ((pos = str.rfind(from,pos)) != string::npos) {
str.replace( pos // position
,from.length() // taille
,to // Chaine de remplacement
);
}
------------------------------------------------------------
Voyez-vous une façon plus simple et plus courte de faire ?
(c'est pour montrer à mon CP que C++ est un language simple et
performant ;-) )
Je veux remplacer , dans un string, une chaîne par une autre. Je recherche la solution la plus simple et la plus claire (pas spécialement la plus optimisée).
Pour l'instant je fais comme ceci : ------------------------------------------------------------ int pos = str.length();
while ((pos = str.rfind(from,pos)) != string::npos) { str.replace( pos // position ,from.length() // taille ,to // Chaine de remplacement ); } ------------------------------------------------------------
Voyez-vous une façon plus simple et plus courte de faire ? (c'est pour montrer à mon CP que C++ est un language simple et performant ;-) )
Pourquoi rfind au lieu de find ?
David
TSalm
Le Wed, 20 Jun 2007 23:04:37 +0200, David Fleury
------------------------------------------------------------ int pos = str.length();
while ((pos = str.rfind(from,pos)) != string::npos) { str.replace( pos // position ,from.length() // taille ,to // Chaine de remplacement ); } ------------------------------------------------------------
Pourquoi rfind au lieu de find ?
Pour éviter des problémes de décalage.
Si par exemple je veux remplacer "BO" par "BOBO" dans la chaine "j'ai un BO" . Il y a des chances qu'il me fasse une boucle infini parce qu'il va chercher et par consequent remplacer sur la chaîne que j'ai inséré. (à moins de rajouter un pos=pos+to.length() ...)
Si je cherche et remplace en arriére, je ne prends pas en considération les endroits modifiés...
Une meilleurs solution ?
Le Wed, 20 Jun 2007 23:04:37 +0200, David Fleury
------------------------------------------------------------
int pos = str.length();
while ((pos = str.rfind(from,pos)) != string::npos) {
str.replace( pos // position
,from.length() // taille
,to // Chaine de remplacement
);
}
------------------------------------------------------------
Pourquoi rfind au lieu de find ?
Pour éviter des problémes de décalage.
Si par exemple je veux remplacer "BO" par "BOBO"
dans la chaine "j'ai un BO" .
Il y a des chances qu'il me fasse une boucle infini parce qu'il va
chercher et par consequent remplacer sur la chaîne que j'ai inséré.
(à moins de rajouter un pos=pos+to.length() ...)
Si je cherche et remplace en arriére, je ne prends pas en
considération les endroits modifiés...
------------------------------------------------------------ int pos = str.length();
while ((pos = str.rfind(from,pos)) != string::npos) { str.replace( pos // position ,from.length() // taille ,to // Chaine de remplacement ); } ------------------------------------------------------------
Pourquoi rfind au lieu de find ?
Pour éviter des problémes de décalage.
Si par exemple je veux remplacer "BO" par "BOBO" dans la chaine "j'ai un BO" . Il y a des chances qu'il me fasse une boucle infini parce qu'il va chercher et par consequent remplacer sur la chaîne que j'ai inséré. (à moins de rajouter un pos=pos+to.length() ...)
Si je cherche et remplace en arriére, je ne prends pas en considération les endroits modifiés...
Une meilleurs solution ?
David Fleury
Le Wed, 20 Jun 2007 23:04:37 +0200, David Fleury
------------------------------------------------------------ int pos = str.length();
while ((pos = str.rfind(from,pos)) != string::npos) { str.replace( pos // position ,from.length() // taille ,to // Chaine de remplacement ); } ------------------------------------------------------------
Pourquoi rfind au lieu de find ?
Pour éviter des problémes de décalage.
Si par exemple je veux remplacer "BO" par "BOBO" dans la chaine "j'ai un BO" . Il y a des chances qu'il me fasse une boucle infini parce qu'il va chercher et par consequent remplacer sur la chaîne que j'ai inséré. (à moins de rajouter un pos=pos+to.length() ...)
Si je cherche et remplace en arriére, je ne prends pas en considération les endroits modifiés...
J'entends bien mais je me demandais si find ( + le décalage ) n'était pas "plus clair" pour un exemple de ce type. l'utilisation de rfind me semblait juste une version déjà "compliqué" dans le sens où elle cache la boucle infinie possible avec find.
Une meilleurs solution ?
Non non. voici juste la version find (qui me semble plus naturellle)
------------------------------------------------------------
int pos = str.length();
while ((pos = str.rfind(from,pos)) != string::npos) {
str.replace( pos // position
,from.length() // taille
,to // Chaine de remplacement
);
}
------------------------------------------------------------
Pourquoi rfind au lieu de find ?
Pour éviter des problémes de décalage.
Si par exemple je veux remplacer "BO" par "BOBO"
dans la chaine "j'ai un BO" .
Il y a des chances qu'il me fasse une boucle infini parce qu'il va
chercher et par consequent remplacer sur la chaîne que j'ai inséré.
(à moins de rajouter un pos=pos+to.length() ...)
Si je cherche et remplace en arriére, je ne prends pas en
considération les endroits modifiés...
J'entends bien mais je me demandais si find ( + le décalage )
n'était pas "plus clair" pour un exemple de ce type.
l'utilisation de rfind me semblait juste une version déjà "compliqué"
dans le sens où elle cache la boucle infinie possible avec find.
Une meilleurs solution ?
Non non. voici juste la version find (qui me semble plus naturellle)
------------------------------------------------------------ int pos = str.length();
while ((pos = str.rfind(from,pos)) != string::npos) { str.replace( pos // position ,from.length() // taille ,to // Chaine de remplacement ); } ------------------------------------------------------------
Pourquoi rfind au lieu de find ?
Pour éviter des problémes de décalage.
Si par exemple je veux remplacer "BO" par "BOBO" dans la chaine "j'ai un BO" . Il y a des chances qu'il me fasse une boucle infini parce qu'il va chercher et par consequent remplacer sur la chaîne que j'ai inséré. (à moins de rajouter un pos=pos+to.length() ...)
Si je cherche et remplace en arriére, je ne prends pas en considération les endroits modifiés...
J'entends bien mais je me demandais si find ( + le décalage ) n'était pas "plus clair" pour un exemple de ce type. l'utilisation de rfind me semblait juste une version déjà "compliqué" dans le sens où elle cache la boucle infinie possible avec find.
Une meilleurs solution ?
Non non. voici juste la version find (qui me semble plus naturellle)
//replace fromstr by tostr from str into result replace_range_copy(str.begin() ,str.end() ,back_inserter(result), fromstr.begin(),fromstr.end(), tostr.begin() ,tostr.end() );
//avec regex //en priant que fromstr n'ai pas de caractères spéciaux boost::regex e(string("(")+fromstr+")"); result=boost::regex_replace(str,e,tostr, boost::match_default | boost::format_all);
Et à condition d'avoir Boost.Regex installé et compilé (puisque regex fait partie des librairies boost à compiler).
Michael
On Jun 20, 1:49 pm, Michael DOUBEZ <michael.dou...@free.fr> wrote:
TSalm a écrit :> Merci à tous.
Je n'avais pas planifié aller jusqu'aux regexp.... mais je me garde
les regexp de Boost de côté.
C'est vraiment une bibliothéque très puissante.
Si c'est juste pour faire un replace, les regexp paraissent un peu
exagérées.
Qui peut le plus, peut le moins. Combien de lignes de code
est-ce qu'il t'a fallu ? Avec boost::regex, une ou deux suffit.
Une fois la fonction générique écrite, la différence n'est pas flagrante:
//replace fromstr by tostr from str into result
replace_range_copy(str.begin() ,str.end() ,back_inserter(result),
fromstr.begin(),fromstr.end(),
tostr.begin() ,tostr.end() );
//avec regex
//en priant que fromstr n'ai pas de caractères spéciaux
boost::regex e(string("(")+fromstr+")");
result=boost::regex_replace(str,e,tostr,
boost::match_default | boost::format_all);
Et à condition d'avoir Boost.Regex installé et compilé (puisque regex
fait partie des librairies boost à compiler).
//replace fromstr by tostr from str into result replace_range_copy(str.begin() ,str.end() ,back_inserter(result), fromstr.begin(),fromstr.end(), tostr.begin() ,tostr.end() );
//avec regex //en priant que fromstr n'ai pas de caractères spéciaux boost::regex e(string("(")+fromstr+")"); result=boost::regex_replace(str,e,tostr, boost::match_default | boost::format_all);
Et à condition d'avoir Boost.Regex installé et compilé (puisque regex fait partie des librairies boost à compiler).
Michael
Michael DOUBEZ
Merci à tous. Je n'avais pas planifié aller jusqu'aux regexp.... mais je me garde les regexp de Boost de côté. C'est vraiment une bibliothéque très puissante.
[snip] Ensuite tu l'utilises sur tes string
//resulting string string result; //replace fromstr by tostr from str into result replace_range_copy(str.begin() ,str.end() ,back_inserter(result), fromstr.begin(),fromstr.end(), tostr.begin() ,tostr.end() );
ouïe, si ça ne donne pas un code clair, ça laisse au moins présumé de l'esprit tordus de son auteur ;-)
Comment ça pas un code clair ? C'est sûr qu'en se limitant aux string, on peut gagner en clareté mais là c'est générique (fonctionne sur basic_strin, vector, list et dequeue en tous cas).
Enfin ce n'est qu'une proposition :)
Michael
Merci à tous.
Je n'avais pas planifié aller jusqu'aux regexp.... mais je me garde
les regexp de Boost de côté.
C'est vraiment une bibliothéque très puissante.
[snip]
Ensuite tu l'utilises sur tes string
//resulting string
string result;
//replace fromstr by tostr from str into result
replace_range_copy(str.begin() ,str.end() ,back_inserter(result),
fromstr.begin(),fromstr.end(),
tostr.begin() ,tostr.end() );
ouïe, si ça ne donne pas un code clair, ça laisse au moins présumé de
l'esprit tordus de son auteur ;-)
Comment ça pas un code clair ?
C'est sûr qu'en se limitant aux string, on peut gagner en clareté mais
là c'est générique (fonctionne sur basic_strin, vector, list et dequeue
en tous cas).
Merci à tous. Je n'avais pas planifié aller jusqu'aux regexp.... mais je me garde les regexp de Boost de côté. C'est vraiment une bibliothéque très puissante.
[snip] Ensuite tu l'utilises sur tes string
//resulting string string result; //replace fromstr by tostr from str into result replace_range_copy(str.begin() ,str.end() ,back_inserter(result), fromstr.begin(),fromstr.end(), tostr.begin() ,tostr.end() );
ouïe, si ça ne donne pas un code clair, ça laisse au moins présumé de l'esprit tordus de son auteur ;-)
Comment ça pas un code clair ? C'est sûr qu'en se limitant aux string, on peut gagner en clareté mais là c'est générique (fonctionne sur basic_strin, vector, list et dequeue en tous cas).
Enfin ce n'est qu'une proposition :)
Michael
Michael DOUBEZ
C'est marrant, le code que tu as écrit fait partie des choses de la librairie standard que je n'utilise jamais parce que je trouve que c'est complètement illisible (quant bien même ce serait concis).
Personnellement, j'ai ma propore classe string, et il me suffit de faire:
text.replace( "old", "new" ).
C'est concis, clair, lisible.
Typiquement, ce genre de fonction ne fait pas partie des fonctions membre. Rien n'empèche d'avoir string& replace(string& str, string& strfrom, string& strto);
Quoique en regardant la taille de l'interface de std::string, on puisse avoir des doutes:)
Michael
C'est marrant, le code que tu as écrit fait partie des choses de la
librairie standard que je n'utilise jamais parce que je trouve que c'est
complètement illisible (quant bien même ce serait concis).
Personnellement, j'ai ma propore classe string, et il me suffit de faire:
text.replace( "old", "new" ).
C'est concis, clair, lisible.
Typiquement, ce genre de fonction ne fait pas partie des fonctions
membre. Rien n'empèche d'avoir
string& replace(string& str, string& strfrom, string& strto);
Quoique en regardant la taille de l'interface de std::string, on puisse
avoir des doutes:)
C'est marrant, le code que tu as écrit fait partie des choses de la librairie standard que je n'utilise jamais parce que je trouve que c'est complètement illisible (quant bien même ce serait concis).
Personnellement, j'ai ma propore classe string, et il me suffit de faire:
text.replace( "old", "new" ).
C'est concis, clair, lisible.
Typiquement, ce genre de fonction ne fait pas partie des fonctions membre. Rien n'empèche d'avoir string& replace(string& str, string& strfrom, string& strto);
Quoique en regardant la taille de l'interface de std::string, on puisse avoir des doutes:)
Michael
Sylvain
Michael DOUBEZ wrote on 21/06/2007 10:45:
text.replace( "old", "new" ).
ce genre de fonction ne fait pas partie des fonctions membre.
ne fait pas partie de l'implémentation de std::string ou ne devrait pas être une fonction membre ?
ce qui ne gênerait (en fait, des fois oui, des fois pas) serait que cette méthode soit mutable; donc un
... comme fonction amie. certes, mais transmettre la chaîne opérande est (supportablement mais inutilement) lourd, se rappeler l'ordre de 2 params est déjà dur, alors 3 ! ;)
Sylvain.
Michael DOUBEZ wrote on 21/06/2007 10:45:
text.replace( "old", "new" ).
ce genre de fonction ne fait pas partie des fonctions membre.
ne fait pas partie de l'implémentation de std::string ou ne devrait pas
être une fonction membre ?
ce qui ne gênerait (en fait, des fois oui, des fois pas) serait que
cette méthode soit mutable; donc un
... comme fonction amie.
certes, mais transmettre la chaîne opérande est (supportablement mais
inutilement) lourd, se rappeler l'ordre de 2 params est déjà dur, alors
3 ! ;)
... comme fonction amie. certes, mais transmettre la chaîne opérande est (supportablement mais inutilement) lourd, se rappeler l'ordre de 2 params est déjà dur, alors 3 ! ;)
Sylvain.
Loïc Joly
Bonjour,
Je veux remplacer , dans un string, une chaîne par une autre. Je recherche la solution la plus simple et la plus claire (pas spécialement la plus optimisée).
Pour l'instant je fais comme ceci : ------------------------------------------------------------ int pos = str.length();
while ((pos = str.rfind(from,pos)) != string::npos) { str.replace( pos // position ,from.length() // taille ,to // Chaine de remplacement ); } ------------------------------------------------------------
Voyez-vous une façon plus simple et plus courte de faire ?
Comme on tas déjà proposé boost, il y a aussi boost::string_algo qui possède un certain nombre de choses assez simples d'emploi (plus que les regex en tout cas, du moin pour qui n'a pas l'habitude de les utiliser tous les jours). En particulier, dans ton cas :
replace_all(str, from, to);
-- Loïc
Bonjour,
Je veux remplacer , dans un string, une chaîne par une autre. Je
recherche la solution la plus simple et la plus claire (pas
spécialement la plus optimisée).
Pour l'instant je fais comme ceci :
------------------------------------------------------------
int pos = str.length();
while ((pos = str.rfind(from,pos)) != string::npos) {
str.replace( pos // position
,from.length() // taille
,to // Chaine de remplacement
);
}
------------------------------------------------------------
Voyez-vous une façon plus simple et plus courte de faire ?
Comme on tas déjà proposé boost, il y a aussi boost::string_algo qui
possède un certain nombre de choses assez simples d'emploi (plus que les
regex en tout cas, du moin pour qui n'a pas l'habitude de les utiliser
tous les jours). En particulier, dans ton cas :
Je veux remplacer , dans un string, une chaîne par une autre. Je recherche la solution la plus simple et la plus claire (pas spécialement la plus optimisée).
Pour l'instant je fais comme ceci : ------------------------------------------------------------ int pos = str.length();
while ((pos = str.rfind(from,pos)) != string::npos) { str.replace( pos // position ,from.length() // taille ,to // Chaine de remplacement ); } ------------------------------------------------------------
Voyez-vous une façon plus simple et plus courte de faire ?
Comme on tas déjà proposé boost, il y a aussi boost::string_algo qui possède un certain nombre de choses assez simples d'emploi (plus que les regex en tout cas, du moin pour qui n'a pas l'habitude de les utiliser tous les jours). En particulier, dans ton cas :
replace_all(str, from, to);
-- Loïc
Michael DOUBEZ
Michael DOUBEZ wrote on 21/06/2007 10:45:
text.replace( "old", "new" ).
ce genre de fonction ne fait pas partie des fonctions membre.
ne fait pas partie de l'implémentation de std::string ou ne devrait pas être une fonction membre ?
Ne devrait pas être une fonction membre. L'implémentation d'un search/replace ne dépend pas à priori de l'implémentation sousjacente alors je ne vois pas l'interet d'encombrer l'interface.
ce qui ne gênerait (en fait, des fois oui, des fois pas) serait que cette méthode soit mutable; donc un
ce genre de fonction ne fait pas partie des fonctions membre.
ne fait pas partie de l'implémentation de std::string ou ne devrait pas
être une fonction membre ?
Ne devrait pas être une fonction membre. L'implémentation d'un
search/replace ne dépend pas à priori de l'implémentation sousjacente
alors je ne vois pas l'interet d'encombrer l'interface.
ce qui ne gênerait (en fait, des fois oui, des fois pas) serait que
cette méthode soit mutable; donc un
ce genre de fonction ne fait pas partie des fonctions membre.
ne fait pas partie de l'implémentation de std::string ou ne devrait pas être une fonction membre ?
Ne devrait pas être une fonction membre. L'implémentation d'un search/replace ne dépend pas à priori de l'implémentation sousjacente alors je ne vois pas l'interet d'encombrer l'interface.
ce qui ne gênerait (en fait, des fois oui, des fois pas) serait que cette méthode soit mutable; donc un
ce genre de fonction ne fait pas partie des fonctions membre.
ne fait pas partie de l'implémentation de std::string ou ne devrait pas être une fonction membre ?
Ne devrait pas être une fonction membre. L'implémentation d'un search/replace ne dépend pas à priori de l'implémentation sousjacente alors je ne vois pas l'interet d'encombrer l'interface.
hmmm, vision différente alors, car pour moi l'implémentation concrète d'une manipulation des données d'une instance dépends bien de ces données, de cette instance ... si la chaîne est par exemple la concaténation de différents segments chainés et partagés, la classe seule (puisque tu ne veux pas même de fct amie) pourra mettre à jour sa liste de segments.
je préférerais donc ne pas encombrer le namespace global (que je préfère le plus vide possible).
je lis ça comme une fonction recevant une /const string&/ et me retournant celle-ci modifiée dans un /string&/ c'est précisément les confusions qu'il ne me paraissait pas utile d'introduire.
Sylvain.
Michael DOUBEZ wrote on 22/06/2007 08:57:
Michael DOUBEZ wrote on 21/06/2007 10:45:
text.replace( "old", "new" ).
ce genre de fonction ne fait pas partie des fonctions membre.
ne fait pas partie de l'implémentation de std::string ou ne devrait
pas être une fonction membre ?
Ne devrait pas être une fonction membre. L'implémentation d'un
search/replace ne dépend pas à priori de l'implémentation sousjacente
alors je ne vois pas l'interet d'encombrer l'interface.
hmmm, vision différente alors, car pour moi l'implémentation concrète
d'une manipulation des données d'une instance dépends bien de ces
données, de cette instance ... si la chaîne est par exemple la
concaténation de différents segments chainés et partagés, la classe
seule (puisque tu ne veux pas même de fct amie) pourra mettre à jour sa
liste de segments.
je préférerais donc ne pas encombrer le namespace global (que je préfère
le plus vide possible).
je lis ça comme une fonction recevant une /const string&/ et me
retournant celle-ci modifiée dans un /string&/ c'est précisément les
confusions qu'il ne me paraissait pas utile d'introduire.
ce genre de fonction ne fait pas partie des fonctions membre.
ne fait pas partie de l'implémentation de std::string ou ne devrait pas être une fonction membre ?
Ne devrait pas être une fonction membre. L'implémentation d'un search/replace ne dépend pas à priori de l'implémentation sousjacente alors je ne vois pas l'interet d'encombrer l'interface.
hmmm, vision différente alors, car pour moi l'implémentation concrète d'une manipulation des données d'une instance dépends bien de ces données, de cette instance ... si la chaîne est par exemple la concaténation de différents segments chainés et partagés, la classe seule (puisque tu ne veux pas même de fct amie) pourra mettre à jour sa liste de segments.
je préférerais donc ne pas encombrer le namespace global (que je préfère le plus vide possible).
je lis ça comme une fonction recevant une /const string&/ et me retournant celle-ci modifiée dans un /string&/ c'est précisément les confusions qu'il ne me paraissait pas utile d'introduire.