[noob] string et remplacement de chaînes

Le
TSalm
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 ;-) )
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 4
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
TSalm
Le #308095
------------------------------------------------------------
int pos = str.length();

while ((pos = str.rfind(from,pos)) != string::npos) {
str.replace( pos // position
,from.length() // taille
,to // Chaine de remplacement
);
}
------------------------------------------------------------



oups, j'ai oublié de préciser que :
str : est la string à transformer
from : là où tu trouve cette chaîne
to: tu la remplace par celle-çi

mais vous l'avez deviné bien évidemment :-)

TSalm

Michael DOUBEZ
Le #308094
------------------------------------------------------------
int pos = str.length();

while ((pos = str.rfind(from,pos)) != string::npos) {
str.replace( pos // position
,from.length() // taille
,to // Chaine de remplacement
);
}
------------------------------------------------------------



oups, j'ai oublié de préciser que :
str : est la string à transformer
from : là où tu trouve cette chaîne
to: tu la remplace par celle-çi

mais vous l'avez deviné bien évidemment :-)


Ca me parait bien.

Remplacer 'int pos' par 'size_t pos'.
Mettre quelques commentaires sur ce que tu fais.

Michael


jeremie fouche
Le #308062
------------------------------------------------------------
int pos = str.length();

while ((pos = str.rfind(from,pos)) != string::npos) {
str.replace( pos // position
,from.length() // taille
,to // Chaine de remplacement
);
}
------------------------------------------------------------



oups, j'ai oublié de préciser que :
str : est la string à transformer
from : là où tu trouve cette chaîne
to: tu la remplace par celle-çi

mais vous l'avez deviné bien évidemment :-)


boost::regex est ton ami :

boost::regex re_replace(from);
str = boost::regex_replace(str, re_replace, to);

je crois qu'avec ça, on peut montrer que le C++ est simple et performant...

Bon, attention tout de même, il faut compiler boost::regex.

HTH
--
Jérémie


Mathias Gaunard
Le #308061

boost::regex est ton ami :

boost::regex re_replace(from);


il faut d'abord échapper dans from tous les caractères spéciaux pour les
expressions régulières (qui dépendent en plus du dialecte utilisé).

str = boost::regex_replace(str, re_replace, to);

je crois qu'avec ça, on peut montrer que le C++ est simple et performant...

Bon, attention tout de même, il faut compiler boost::regex.


Tu peux la compiler à la compilation avec boost::xpressive.


HTH


TSalm
Le #308023
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.
Michael DOUBEZ
Le #307983
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.

Au pire tu peux te refaire un algo du type:
template <class ForwardIteratorI, //Input Forward Iterator
class OutputIterator, //Copy Output Iterator
class ForwardIteratorS, //Search Forward Iterator
class ForwardIteratorR> //Replace Forward Iterator
OutputIterator replace_range_copy (
ForwardIteratorI first,
ForwardIteratorI last,
OutputIterator result,
ForwardIteratorS search_first,
ForwardIteratorS search_last,
ForwardIteratorR replace_first,
ForwardIteratorR replace_last
)
{
while(first!=last)
{
if(*first==*search_first)
{ //perhaps a match
ForwardIteratorI tmp1(first);
ForwardIteratorS tmp2(search_first);
do
{
//increase comparison
++tmp1;++tmp2;
if(tmp2==search_last)
{ //end of search - success
result=copy(replace_first,replace_last,result);
//update first
first=tmp1;
break;
}
else if ( tmp1 == last )
{ // no further search
result=copy(first,last,result);
first=last;
break;
}
else if ( *tmp1 != *tmp2 )
{ //no match
*result++=*first++;
break;
}
} while(1);
}
else
{ //no match
*result++=*first++;
}
}
return result;
}

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

Michael

James Kanze
Le #307952
On Jun 20, 1:49 pm, Michael DOUBEZ
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.

--
James Kanze (GABI Software, from CAI) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Guillaume GOURDIN
Le #307951
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.



TSalm wrote:
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 ;-) )




TSalm
Le #307950
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.



Au pire tu peux te refaire un algo du type:
template <class ForwardIteratorI, //Input Forward Iterator
class OutputIterator, //Copy Output Iterator
class ForwardIteratorS, //Search Forward Iterator
class ForwardIteratorR> //Replace Forward Iterator
OutputIterator replace_range_copy (
ForwardIteratorI first,
ForwardIteratorI last,
OutputIterator result,
ForwardIteratorS search_first,
ForwardIteratorS search_last,
ForwardIteratorR replace_first,
ForwardIteratorR replace_last
)
{
while(first!=last)
{
if(*first==*search_first)
{ //perhaps a match
ForwardIteratorI tmp1(first);
ForwardIteratorS tmp2(search_first);
do
{
//increase comparison
++tmp1;++tmp2;
if(tmp2==search_last)
{ //end of search - success
result=copy(replace_first,replace_last,result);
//update first
first=tmp1;
break;
}
else if ( tmp1 == last )
{ // no further search
result=copy(first,last,result);
first=last;
break;
}
else if ( *tmp1 != *tmp2 )
{ //no match
*result++=*first++;
break;
}
} while(1);
}
else
{ //no match
*result++=*first++;
}
}
return result;
}

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


TSalm
Le #307949
Le Wed, 20 Jun 2007 18:08:37 +0200, Guillaume GOURDIN
Personnellement, j'ai ma propore classe string, et il me suffit de faire:

text.replace( "old", "new" ).

C'est concis, clair, lisible.


c'est une librairie que vous avez faites vous-même ou on peut la
trouver quelque part ?

Publicité
Poster une réponse
Anonyme