Ersetzen Sie einen Teil einer Zeichenfolge durch eine andere Zeichenfolge

Lesezeit: 7 Minuten

Ersetzen Sie einen Teil einer Zeichenfolge durch eine andere Zeichenfolge
Tom Leese

Ist es in C++ möglich, einen Teil einer Zeichenfolge durch eine andere Zeichenfolge zu ersetzen?

Grundsätzlich möchte ich folgendes tun:

QString string("hello $name");
string.replace("$name", "Somename");

Aber ich möchte die Standard-C++-Bibliotheken verwenden.

  • mögliches Duplikat von Was ist die Funktion zum Ersetzen von Zeichenfolgen in C? — oops tut mir leid, das ist C, nicht C++; Ich wünschte, ich könnte abstimmen.

    – polygenelubricants

    5. August 2010 um 19:10 Uhr


  • @poly Ich würde denken, dass dies auch nach C++ gefragt worden sein muss, aber ich kann es nicht finden

    – Michael Mrozek

    5. August 2010 um 19:15 Uhr

  • Es gibt ein std-Tag für die Frage, aber vielleicht interessieren Sie sich vielleicht für die Zeichenfolgenalgorithmen von Boost, die auch eine große Auswahl an Ersetzungsalgorithmen enthalten (inplace/copy, case sensitive/case insensitive, replace first/last/all/n-th ).

    – Onkel Bens

    5. August 2010 um 22:25 Uhr

  • @Michael Mrozek Es gibt einen unter stackoverflow.com/questions/3418231/… aber er ist neuer und Ihre replaceAll-Methode hier ist robuster.

    – dave-holm

    21. Juni 2011 um 4:40 Uhr


  • mögliches Duplikat von Wie suche/finde und ersetze ich in einer Standardzeichenfolge?

    – Strahl

    23. Juni 2015 um 19:59 Uhr

Ersetzen Sie einen Teil einer Zeichenfolge durch eine andere Zeichenfolge
Michael Mrozek

Es gibt eine Funktion, um einen Teilstring innerhalb eines Strings zu finden (find) und eine Funktion zum Ersetzen eines bestimmten Bereichs in einer Zeichenfolge durch eine andere Zeichenfolge (replace), sodass Sie diese kombinieren können, um den gewünschten Effekt zu erzielen:

bool replace(std::string& str, const std::string& from, const std::string& to) {
    size_t start_pos = str.find(from);
    if(start_pos == std::string::npos)
        return false;
    str.replace(start_pos, from.length(), to);
    return true;
}

std::string string("hello $name");
replace(string, "$name", "Somename");

Als Antwort auf einen Kommentar, denke ich replaceAll würde wohl so aussehen:

void replaceAll(std::string& str, const std::string& from, const std::string& to) {
    if(from.empty())
        return;
    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(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
    }
}

  • Wie würde ich es beheben, wenn die ursprüngliche Zeichenfolge mehr als eine Instanz von “$name” hätte und ich alle ersetzen wollte.

    – Tom Leese

    5. August 2010 um 19:14 Uhr

  • Warum nicht from und to bestanden pro const Hinweis? Was bedeutet Ihre Funktion, wenn from gibt es nicht? -1 von mir dafür.

    – sbi

    5. August 2010 um 19:15 Uhr


  • @sbi Behoben, obwohl Sie es als Empfehlungen anstelle von Angriffen hätten formulieren können – es ist mir einfach nicht in den Sinn gekommen, ich denke selten daran, es zu verwenden const und wenn ich eine Hilfsmethode wie diese schrieb, würde ich sie nur aufrufen, wenn ich wüsste, dass die Ersetzung gültig ist

    – Michael Mrozek

    5. August 2010 um 19:19 Uhr


  • @Michael: Gut, ich habe meine Ablehnung in eine positive umgewandelt. Entlassung const vernachlässigt eines der besten Tools von C++. Passieren pro const reference sollte der Standardmodus für Funktionsparameter sein. (FTR, ohne die constSie könnten nicht einmal Zeichenfolgenliterale an Ihre Funktion übergeben, da Sie keine Temporäre an Nicht-const Verweise. Die Funktion würde also nicht einmal das tun, wofür sie geschrieben wurde.)

    – sbi

    5. August 2010 um 21:13 Uhr


  • Ist das auch 2018 noch die einzige Lösung? Wenn dies der Fall ist und irgendein C++-Komitee dies liest, klären Sie es. Es ist peinlich. split(string, string) und replace(string, string) bitte!

    – Benutzer997112

    31. Juli 2018 um 12:53 Uhr

1647139212 849 Ersetzen Sie einen Teil einer Zeichenfolge durch eine andere Zeichenfolge
Tom

Mit C++11 können Sie verwenden std::regex so:

#include <regex>
...
std::string string("hello $name");
string = std::regex_replace(string, std::regex("\\$name"), "Somename");

Der doppelte Backslash ist erforderlich, um ein Escape-Zeichen zu maskieren.

  • Ich bin mir ziemlich sicher std::regex_replace akzeptiert den Qt-String nicht.

    – BartoszKP

    23. Juli 2015 um 19:06 Uhr

  • Du hast recht. Zufälligerweise stellt QString eine Ersetzungsmethode bereit, die ein QRexExp akzeptiert, wodurch die Verwendung von Qt-eigenem Material ermöglicht wird. Aber ich denke, die aktuelle Antwort könnte durch Ersetzen korrigiert werden string mit string.toStdString().

    – Tom

    24. Juli 2015 um 22:36 Uhr

  • Oder einfach durch wechseln String zu std::string, weil die Frage nichts mit Qt zu tun hat. Bitte erwägen Sie dies – ich werde Ihre Antwort danach gerne positiv bewerten.

    – BartoszKP

    25. Juli 2015 um 10:07 Uhr

  • Raw-String ermöglicht das Schreiben R"(\$name)" anstatt "\\$name".

    – Jarod42

    22. Juli 2016 um 12:30 Uhr

  • Wie viel wird dies langsamer sein als Suchen/Ersetzen, ohne die Konstruktionszeit von std::regex zu berücksichtigen?

    – jw_

    29. Dezember 2019 um 12:14 Uhr

1647139213 689 Ersetzen Sie einen Teil einer Zeichenfolge durch eine andere Zeichenfolge
SC Madsen

std::string hat ein replace Methode, ist es das, was Sie suchen?

Du könntest es versuchen:

s.replace(s.find("$name"), sizeof("$name") - 1, "Somename");

Ich habe es selbst nicht ausprobiert, sondern nur die Dokumentation gelesen find() und replace().

  • Soweit ich sehen kann, nimmt die std::string replace-Methode nicht zwei Strings, wie ich möchte.

    – Tom Leese

    5. August 2010 um 19:10 Uhr

  • Das funktioniert bei mir nicht. sizeof sollte durch string(“Somename”).size()-1 ersetzt werden

    – Tim Zaman

    10. April 2014 um 8:34 Uhr


  • @TimZaman: Das verwirrt mich, die Dokumentation besagt eindeutig, dass Sie von einer Zeichenfolge im C-Stil initialisieren können.

    – SC Madsen

    10. April 2014 um 18:26 Uhr

  • das 2. Argument sollte die Länge von “$name” sein (statt der Länge von “Somename”), oder?

    – Daniel Kuss

    13. Januar 2016 um 19:56 Uhr

  • Dies würde nicht funktionieren, wenn es mehrere Vorkommen von gibt "$name" in s Schnur.

    – Bimbi

    31. Mai 2021 um 3:10 Uhr

1647139213 160 Ersetzen Sie einen Teil einer Zeichenfolge durch eine andere Zeichenfolge
Zarek Tomczak

Verwenden Sie Folgendes, um die neue Zeichenfolge zurückzugeben:

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

Wenn Sie Leistung benötigen, finden Sie hier eine optimierte Funktion, die die Eingabezeichenfolge ändert und keine Kopie der Zeichenfolge erstellt:

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 modified: " 
          << input << std::endl;

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

Ausgabe:

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

Das klingt nach einer Option

string.replace(string.find("%s"), string("%s").size(), "Something");

Sie könnten dies in eine Funktion packen, aber diese einzeilige Lösung klingt akzeptabel. Das Problem ist, dass dies nur das erste Vorkommen ändert, Sie möchten vielleicht eine Schleife darüber machen, aber es erlaubt Ihnen auch, mehrere Variablen mit demselben Token in diese Zeichenfolge einzufügen (%s)

  • Gefällt mir vom Stil, fand aber die unterschiedlichen Saiten verwirrend ^^ str.replace(str.find("%s"), string("%s").size(), "Something");

    – Paul Würtz

    23. April 2017 um 14:18 Uhr


1647139214 840 Ersetzen Sie einen Teil einer Zeichenfolge durch eine andere Zeichenfolge
Zeichnete Noakes

Ja, Sie können das tun, aber Sie müssen die Position des ersten Strings mit dem Element find() von string finden und dann durch das Element replace() ersetzen.

string s("hello $name");
size_type pos = s.find( "$name" );
if ( pos != string::npos ) {
   s.replace( pos, 5, "somename" );   // 5 = length( $name )
}

Wenn Sie vorhaben, die Standardbibliothek zu verwenden, sollten Sie sich unbedingt ein Exemplar des Buches besorgen Die C++-Standardbibliothek die all diese Dinge sehr gut abdeckt.

  • Gefällt mir vom Stil, fand aber die unterschiedlichen Saiten verwirrend ^^ str.replace(str.find("%s"), string("%s").size(), "Something");

    – Paul Würz

    23. April 2017 um 14:18 Uhr


Ich benutze allgemein das:

std::string& replace(std::string& s, const std::string& from, const std::string& to)
{
    if(!from.empty())
        for(size_t pos = 0; (pos = s.find(from, pos)) != std::string::npos; pos += to.size())
            s.replace(pos, from.size(), to);
    return s;
}

Es ruft immer wieder an std::string::find() um andere Vorkommen der gesuchten Zeichenkette zu finden bis std::string::find() findet nichts. Weil std::string::find() gibt die zurück Position des Spiels haben wir nicht das Problem, Iteratoren ungültig zu machen.

995720cookie-checkErsetzen Sie einen Teil einer Zeichenfolge durch eine andere Zeichenfolge

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy