143 votes

Remplacer une sous-chaîne par une autre sous-chaîne C++

Comment remplacer une sous-chaîne dans une chaîne par une autre sous-chaîne en C++, quelles fonctions puis-je utiliser ?

eg: string test = "abc def abc def";
test.replace("abc", "hij").replace("def", "klm"); //replace occurrence of abc and def with other substring

23voto

Czarek Tomczak Points 4551

Remplacer les sous-chaînes ne devrait pas être si difficile.

std::string ReplaceString(std::string subject, const std::string& search,
                          const std::string& replace) {
    size_t pos = 0;
    while((pos = subject.find(search, pos)) != std::string::npos) {
         subject.replace(pos, search.length(), replace);
         pos += replace.length();
    }
    return subject;
}

Si vous avez besoin de performances, voici une fonction optimisée qui modifie la chaîne d'entrée, elle ne crée pas de copie de la chaîne :

void ReplaceStringInPlace(std::string& subject, const std::string& search,
                          const std::string& replace) {
    size_t pos = 0;
    while((pos = subject.find(search, pos)) != std::string::npos) {
         subject.replace(pos, search.length(), replace);
         pos += replace.length();
    }
}

Tests :

std::string input = "abc abc def";
std::cout << "Input string: " << input << std::endl;

std::cout << "ReplaceString() return value: " 
          << ReplaceString(input, "bc", "!!") << std::endl;
std::cout << "ReplaceString() input string not changed: " 
          << input << std::endl;

ReplaceStringInPlace(input, "bc", "??");
std::cout << "ReplaceStringInPlace() input string modified: " 
          << input << std::endl;

Sortie :

Input string: abc abc def
ReplaceString() return value: a!! a!! def
ReplaceString() input string not modified: abc abc def
ReplaceStringInPlace() input string modified: a?? a?? def

12voto

Altinsystems Points 76
std::string replace(std::string str, std::string substr1, std::string substr2)
{
    for (size_t index = str.find(substr1, 0); index != std::string::npos && substr1.length(); index = str.find(substr1, index + substr2.length() ) )
        str.replace(index, substr1.length(), substr2);
    return str;
}

Une solution courte où vous n'avez pas besoin de bibliothèques supplémentaires.

7voto

Michael Burr Points 181287
using std::string;

string string_replace( string src, string const& target, string const& repl)
{
    // handle error situations/trivial cases

    if (target.length() == 0) {
        // searching for a match to the empty string will result in 
        //  an infinite loop
        //  it might make sense to throw an exception for this case
        return src;
    }

    if (src.length() == 0) {
        return src;  // nothing to match against
    }

    size_t idx = 0;

    for (;;) {
        idx = src.find( target, idx);
        if (idx == string::npos)  break;

        src.replace( idx, target.length(), repl);
        idx += repl.length();
    }

    return src;
}

Puisque ce n'est pas un membre de la string elle ne permet pas une syntaxe aussi agréable que celle de votre exemple, mais l'exemple suivant est équivalent :

test = string_replace( string_replace( test, "abc", "hij"), "def", "klm")

4voto

ch0kee Points 522

Si vous êtes sûr que la sous-chaîne requise est présente dans la chaîne de caractères, alors cette fonction remplacera la première occurrence de "abc" a "hij"

test.replace( test.find("abc"), 3, "hij");

Il se plantera si vous n'avez pas "abc" dans test, donc utilisez-le avec précaution.

4voto

Neoh Points 4186

En généralisant la réponse de rotmax, voici une solution complète pour rechercher et remplacer toutes les instances d'une chaîne de caractères. Si les deux sous-chaînes sont de taille différente, la sous-chaîne est remplacée en utilisant string::erase et string::insert, sinon c'est string::replace, plus rapide, qui est utilisé.

void FindReplace(string& line, string& oldString, string& newString) {
  const size_t oldSize = oldString.length();

  // do nothing if line is shorter than the string to find
  if( oldSize > line.length() ) return;

  const size_t newSize = newString.length();
  for( size_t pos = 0; ; pos += newSize ) {
    // Locate the substring to replace
    pos = line.find( oldString, pos );
    if( pos == string::npos ) return;
    if( oldSize == newSize ) {
      // if they're same size, use std::string::replace
      line.replace( pos, oldSize, newString );
    } else {
      // if not same size, replace by erasing and inserting
      line.erase( pos, oldSize );
      line.insert( pos, newString );
    }
  }
}

Prograide.com

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.

Powered by:

X