Wie ersetzt man alle Vorkommen eines Zeichens in der Zeichenkette?

Was ist der effektive Weg, um alle Vorkommen eines Charakters durch ein anderes Zeichen in std::string zu ersetzen?

Solutions Collecting From Web of "Wie ersetzt man alle Vorkommen eines Zeichens in der Zeichenkette?"

std::string enthält keine solche function, aber Sie können die Standalone-function replace from algorithm header verwenden.

 #include  #include  void some_func() { std::string s = "example string"; std::replace( s.begin(), s.end(), 'x', 'y'); // replace all 'x' to 'y' } 

Ich dachte, ich würde auch die Boost-Lösung eincasting:

 #include  // in place std::string in_place = "blah#blah"; boost::replace_all(in_place, "#", "@"); // copy const std::string input = "blah#blah"; std::string output = boost::replace_all_copy(input, "#", "@"); 

Die Frage konzentriert sich auf character Ersetzung von character , aber da ich diese Seite sehr nützlich finde (insbesondere Konrads Bemerkung), möchte ich diese allgemeinere Implementierung teilen, die es erlaubt, auch mit substrings umzugehen:

 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(); // Handles case where 'to' is a substring of 'from' } return str; } 

Verwendung:

 std::cout < < ReplaceAll(string("Number Of Beans"), 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; 

Ausgänge:

Nummer_der_Beans

XXjXugtXty

hhjhugthty


BEARBEITEN:

Obiges kann in geeigneterer Weise implementiert werden, falls die Performances Ihnen am Herzen liegen, indem Sie nichts zurückgeben ( void ) und die Änderungen direkt an der String- str ausführen, die als Argument übergeben wird und an Adresse statt an Wert übergeben wird . Dies würde unnötige und teure Kopie der ursprünglichen Zeichenfolge vermeiden, während das Ergebnis zurückgegeben wird. Ihr Anruf, dann ...

Code:

 static inline void ReplaceAll2(std::string &str, const std::string& from, const std::string& to) { // Same inner code... // No return statement } 

Hoffe, dass dies für einige andere hilfreich sein wird ...

Stellen Sie sich einen großen binären Blob vor, bei dem alle 0x00 Bytes durch “\ 1 \ x30” und alle 0x01 Bytes durch “\ 1 \ x31” ersetzt werden sollen, da das Transportprotokoll keine \ 0-Bytes erlaubt.

In Fällen, in denen

  • der Ersatz und der zu ersetzende String haben unterschiedliche Längen,
  • Es gibt viele Vorkommnisse der zu ersetzenden Zeichenfolge in der Quellzeichenfolge und
  • Die Quellzeichenfolge ist groß.

Die bereitgestellten Lösungen können nicht angewendet werden (weil sie nur einzelne Zeichen ersetzen) oder haben ein performancesproblem, weil sie mehrmals string :: replace aufrufen würden, was immer wieder Kopien der Größe des Blobs erzeugt. (Ich kenne die Boost-Lösung nicht, vielleicht ist es ok aus dieser Perspektive)

Dieser geht alle Vorkommen in der Quell-Saite entlang und baut die neue Saite Stück für Stück auf:

 void replaceAll(std::string& source, const std::string& from, const std::string& to) { std::string newString; newString.reserve(source.length()); // avoids a few memory allocations std::string::size_type lastPos = 0; std::string::size_type findPos; while(std::string::npos != (findPos = source.find(from, lastPos))) { newString.append(source, lastPos, findPos - lastPos); newString += to; lastPos = findPos + from.length(); } // Care for the rest after last occurrence newString += source.substr(lastPos); source.swap(newString); } 

Ein einfaches Suchen und Ersetzen für ein einzelnes Zeichen würde etwa so aussehen:

s.replace(s.find("x"), 1, "y")

Um dies für die gesamte Saite zu tun, wäre es leicht, eine Schleife zu machen, bis Ihr s.find beginnt, npos . Ich nehme an, du könntest auch range_error , um die Schleife zu verlassen, aber das ist irgendwie hässlich.

Wie Kirill vorgeschlagen hat, verwenden Sie entweder die Ersetzungsmethode oder iterieren Sie entlang der Zeichenfolge, wobei Sie jedes Zeichen unabhängig ersetzen.

Alternativ können Sie die find Methode oder find_first_of je nachdem, was Sie tun müssen. Keine dieser Lösungen wird die Aufgabe auf einmal erledigen, aber mit ein paar zusätzlichen Codezeilen sollten Sie dafür sorgen, dass sie für Sie arbeiten. 🙂

Wenn Sie mehr als ein einzelnes Zeichen ersetzen möchten und nur mit std::string , würde dieses Snippet funktionieren und sNeedle in sHaystack durch sReplace ersetzen. SNeedle und sReplace müssen nicht dieselbe Größe haben. Diese Routine verwendet die while-Schleife, um alle Vorkommen zu ersetzen, und nicht nur die erste, die von links nach rechts gefunden wird.

 while(sHaystack.find(sNeedle) != std::string::npos) { sHaystack.replace(sHaystack.find(sNeedle),sNeedle.size(),sReplace); } 
 #include  #include  using namespace std; // Replace function.. string replace(string word, string target, string replacement){ int len, loop=0; string nword="", let; len=word.length(); len--; while(loop< =len){ let=word.substr(loop, 1); if(let==target){ nword=nword+replacement; }else{ nword=nword+let; } loop++; } return nword; } //Main.. int main() { string word; cout<<"Enter Word: "; cin>>word; cout<  

Das funktioniert! Ich habe etwas ähnliches für eine Buchhandlung App verwendet, wo das Inventar in einer CSV (wie eine .dat-Datei) gespeichert wurde. Bei einem einzelnen Zeichen, dh der Ersetzer ist nur ein einzelnes Zeichen, z. B. ‘|’, muss er in Anführungszeichen “|” um eine ungültige Konvertierung const char nicht zu casting.

 #include  #include  using namespace std; int main() { int count = 0; // for the number of occurences. // final hold variable of corrected word up to the npos=j string holdWord = ""; // a temp var in order to replace 0 to new npos string holdTemp = ""; // a csv for a an entry in a book store string holdLetter = "Big Java 7th Ed,Horstman,978-1118431115,99.85"; // j = npos for (int j = 0; j < holdLetter.length(); j++) { if (holdLetter[j] == ',') { if ( count == 0 ) { holdWord = holdLetter.replace(j, 1, " | "); } else { string holdTemp1 = holdLetter.replace(j, 1, " | "); // since replacement is three positions in length, // must replace new replacement's 0 to npos-3, with // the 0 to npos - 3 of the old replacement holdTemp = holdTemp1.replace(0, j-3, holdWord, 0, j-3); holdWord = ""; holdWord = holdTemp; } holdTemp = ""; count++; } } cout << holdWord << endl; return 0; } // result: Big Java 7th Ed | Horstman | 978-1118431115 | 99.85 

Normalerweise verwende ich momentan CentOS, daher ist meine Compiler-Version unten. Die C ++ - Version (g ++), C ++ 98 Standard:

 g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4) Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

Wenn Sie bereit sind, std::string s zu verwenden, können Sie die strsub function dieser Beispielanwendung strsub verwenden oder aktualisieren, wenn Sie einen anderen Typ oder eine andere Gruppe von Parametern verwenden möchten, um ungefähr das gleiche Ziel zu erreichen. Im Grunde verwendet es die Eigenschaften und functionen von std::string , um die übereinstimmenden Zeichen schnell zu löschen und die gewünschten Zeichen direkt in die std::string einzufügen. Jedes Mal, wenn dieser Ersetzungsvorgang ausgeführt wird, wird der Offset aktualisiert, wenn immer noch übereinstimmende Zeichen gefunden werden können. Wenn er nicht ersetzt werden kann, gibt er die Zeichenfolge in ihrem Status von der letzten Aktualisierung zurück.

 #include  #include  std::string strsub(std::string stringToModify, std::string charsToReplace, std::string replacementChars); int main() { std::string silly_typos = "annoiiyyyng syyyllii tiipos."; std::cout < < "Look at these " << silly_typos << std::endl; silly_typos = strsub(silly_typos, "yyy", "i"); std::cout << "After a little elbow-grease, a few less " << silly_typos << std::endl; silly_typos = strsub(silly_typos, "ii", "y"); std::cout << "There, no more " << silly_typos << std::endl; return 0; } std::string strsub(std::string stringToModify, std::string charsToReplace, std::string replacementChars) { std::string this_string = stringToModify; std::size_t this_occurrence = this_string.find(charsToReplace); while (this_occurrence != std::string::npos) { this_string.erase(this_occurrence, charsToReplace.size()); this_string.insert(this_occurrence, replacementChars); this_occurrence = this_string.find(charsToReplace, this_occurrence + replacementChars.size()); } return this_string; } 

Wenn Sie sich nicht darauf verlassen wollen, std::string s als Parameter zu verwenden, können Sie stattdessen Strings im C-Stil übergeben. Sie können das aktualisierte Beispiel unten sehen:

 #include  #include  std::string strsub(const char * stringToModify, const char * charsToReplace, const char * replacementChars, uint64_t sizeOfCharsToReplace, uint64_t sizeOfReplacementChars); int main() { std::string silly_typos = "annoiiyyyng syyyllii tiipos."; std::cout < < "Look at these " << silly_typos << std::endl; silly_typos = strsub(silly_typos.c_str(), "yyy", "i", 3, 1); std::cout << "After a little elbow-grease, a few less " << silly_typos << std::endl; silly_typos = strsub(silly_typos.c_str(), "ii", "y", 2, 1); std::cout << "There, no more " << silly_typos << std::endl; return 0; } std::string strsub(const char * stringToModify, const char * charsToReplace, const char * replacementChars, uint64_t sizeOfCharsToReplace, uint64_t sizeOfReplacementChars) { std::string this_string = stringToModify; std::size_t this_occurrence = this_string.find(charsToReplace); while (this_occurrence != std::string::npos) { this_string.erase(this_occurrence, sizeOfCharsToReplace); this_string.insert(this_occurrence, replacementChars); this_occurrence = this_string.find(charsToReplace, this_occurrence + sizeOfReplacementChars); } return this_string; } 

Für einfache Situationen funktioniert das ziemlich gut, ohne eine andere Bibliothek als std :: string (die bereits verwendet wird) zu verwenden.

Ersetzen Sie alle Vorkommen von Zeichen a durch Zeichen b in some_string :

 for (size_t i = 0; i < some_string.size(); ++i) { if (some_string[i] == 'a') { some_string.replace(i, 1, "b"); } } 

Wenn die Zeichenfolge groß ist oder mehrere zu ersetzende Aufrufe ein Problem darstellen, können Sie die in dieser Antwort genannte Technik anwenden: https://stackoverflow.com/a/29752943/3622300

Alte Schule 🙂

  string pth = "H:/recursos/audio/youtube/libre/falta/"; for(int i=0 ;i< =pth.size(); i++) if(pth[i]=='/') pth[i]='\\'; cout< 

Ergebnis: "H: \ recursos \ audio \ youtube \ libre \ falta \";