Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[noob] string et remplacement de chaînes

37 réponses
Avatar
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 ;-) )

10 réponses

1 2 3 4
Avatar
TSalm
------------------------------------------------------------
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

Avatar
Michael DOUBEZ
------------------------------------------------------------
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


Avatar
jeremie fouche
------------------------------------------------------------
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


Avatar
Mathias Gaunard

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


Avatar
TSalm
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.
Avatar
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.

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

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

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


Avatar
Guillaume GOURDIN
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 ;-) )




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


Avatar
TSalm
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 ?

1 2 3 4