Wie ersetzt man alle Vorkommen eines Zeichens in einer Zeichenfolge?

Lesezeit: 8 Minuten

Wie ersetzt man alle Vorkommen eines Zeichens in einer Zeichenfolge
groß-z

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

  • Es scheint, dass stdlib scheiße ist, wenn es um solche “erweiterten” Funktionen geht. Verwenden Sie besser QString oder eine allgemeine Bibliothek, wenn Sie anfangen, fehlende Dinge zu finden.

    – Kiruahxh

    17. März 2021 um 16:14 Uhr

1647107409 241 Wie ersetzt man alle Vorkommen eines Zeichens in einer Zeichenfolge
Kirill V. Ljadwinski

std::string enthält keine solche Funktion, aber Sie könnten eigenständig verwenden replace Funktion ab algorithm Header.

#include <algorithm>
#include <string>

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

  • std::string ist ein Container speziell für den Betrieb mit Zeichenfolgen entwickelt. Verknüpfung

    – Kirill W. Ljadwinski

    24. Mai 2010 um 11:41 Uhr

  • Leider erlaubt dies, nur ein Zeichen durch ein anderes Zeichen zu ersetzen. Es kann ein Zeichen nicht durch mehr Zeichen (dh durch eine Zeichenfolge) ersetzen. Gibt es eine Möglichkeit, eine Suche durch mehr Zeichen zu ersetzen?

    – SasQ

    9. August 2012 um 9:26 Uhr

  • @ Kirill V. Lyadvinsky Was ist, wenn ich nur ein Vorkommen entfernen möchte.

    – SIFE

    22. November 2012 um 14:54 Uhr

  • @KirillV.Lyadvinsky: Wenn ich diese Methode verwende, um alle x durch y zu ersetzen, ist das Ergebnis eine lange y-Zeichenfolge, unabhängig von der ursprünglichen Zeichenfolge. Mich würde mal interessieren, was deiner Meinung nach das Problem sein könnte. (der code ist genau der gleiche wie du geschrieben hast)

    – Transzendent

    17. Oktober 2013 um 12:08 Uhr

  • @Transcendent: Genau das passiert mit std::string::replace() anstatt std::replace()! ‘x’ (char) wird implizit gecastet size_t [value 120]also wird die ganze Zeichenfolge oder ein Teil davon mit 120 Kopien von ‘y’ aufgefüllt.

    – IBue

    19. Februar 2015 um 18:41 Uhr

1647107410 890 Wie ersetzt man alle Vorkommen eines Zeichens in einer Zeichenfolge
Gauthier Boaglio

Im Mittelpunkt steht die Frage character Ersatz, aber da ich diese Seite sehr nützlich fand (insbesondere Konrads Bemerkung), möchte ich diese allgemeinere Implementierung teilen, die es ermöglicht, damit umzugehen substrings auch:

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

Verwendungszweck:

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:

Number_Of_Beans

XXjXugtXty

hhhhhhhhhhhhhhhhhhhhhhhhhhhhhck


BEARBEITEN:

Das oben Gesagte kann besser umgesetzt werden, falls Sie Leistungen betreffen, indem Sie nichts zurücksenden (void) und die Änderungen direkt an der Zeichenfolge vornehmen str als Argument angegeben, bestanden nach Adresse anstatt nach Wert. Dies würde ein nutzloses und kostspieliges Kopieren 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, das wird für einige andere hilfreich sein …

  • Dieser hat ein Leistungsproblem in Fällen, in denen die Quellzeichenfolge groß ist und die zu ersetzende Zeichenfolge häufig vorkommt. string::replace() würde viele Male aufgerufen werden, was viele String-Kopien verursacht. Siehe meine Lösung, die dieses Problem behebt.

    – Ingmar

    21. April 2015 um 6:44 Uhr


  • Nit-Picking voraus: nach Adresse => per Referenz. Ob es sich um eine Adresse handelt oder nicht, ist ein Implementierungsdetail.

    – Max Truxa

    18. Mai 2015 um 16:16 Uhr

  • Sollte man eigentlich prüfen, ob from string ist leer, sonst kommt es zu einer Endlosschleife.

    – Neuling

    5. September 2015 um 2:23 Uhr

Wie ersetzt man alle Vorkommen eines Zeichens in einer Zeichenfolge
Onkel Zeiv

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

#include <boost/algorithm/string/replace.hpp>

// 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, "#", "@");

  • Dann fehlen dir ein paar -I Flags für Ihren Compiler, damit er die Boost-Bibliotheken auf Ihrem System findet. Vielleicht müssen Sie es sogar zuerst installieren.

    – Martin Ueding

    17. Mai 2019 um 9:56 Uhr

  • Das obige ist effektiver, da es mit std lib herauskommt. Nicht alle verwenden die Boost-Bibliothek 😉

    – hfrmobil

    20. März 2020 um 10:49 Uhr

1647107410 160 Wie ersetzt man alle Vorkommen eines Zeichens in einer Zeichenfolge
Ingmar

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

In Fällen, in denen:

  • der ersetzende und der zu ersetzende String haben unterschiedliche Längen,
  • Es gibt viele Vorkommen der zu ersetzenden Zeichenfolge innerhalb 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 Performance-Problem, weil sie string::replace mehrmals aufrufen würden, was immer wieder Kopien der Größe des Blobs erzeugt. (Ich kenne die Boost-Lösung nicht, vielleicht ist es aus dieser Perspektive in Ordnung)

Dieser geht alle Vorkommen im Quellstring ab und baut den neuen String Stück für Stück auf Einmal:

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 am einfachsten, bis zu Ihrer zu loopen s.find beginnt zurückzukehren npos. Ich nehme an, Sie könnten auch fangen range_error um die Schleife zu verlassen, aber das ist irgendwie hässlich.

  • Dies ist zwar wahrscheinlich eine geeignete Lösung, wenn die Anzahl der zu ersetzenden Zeichen im Vergleich zur Länge der Zeichenfolge klein ist, aber es lässt sich nicht gut skalieren. Wenn der Anteil der zu ersetzenden Zeichen in der ursprünglichen Zeichenfolge zunimmt, nähert sich diese Methode zeitlich O(N^2).

    – und und

    24. Mai 2010 um 14:37 Uhr

  • Wahr. Meine allgemeine Philosophie ist es, das Einfache (zu schreiben und zu lesen) zu tun, bis die Ineffizienzen echte Probleme verursachen. Es gibt einige Umstände, in denen Sie möglicherweise riesige Saiten haben, bei denen O (N ** 2) wichtig ist, aber in 99% der Fälle sind meine Saiten 1K oder weniger.

    – TED

    25. Mai 2010 um 3:40 Uhr

  • … davon abgesehen gefällt mir Kirills Methode besser (und hatte sie bereits positiv bewertet).

    – TED

    25. Mai 2010 um 3:41 Uhr

  • Was passiert, wenn “x” nicht gefunden wird? Und warum verwendest du doppelte Klammern?

    – Prasath Govind

    25. August 2015 um 11:26 Uhr

  • @PrasathGovind – Ich habe nur die erforderlichen Anrufe angezeigt (daher “so etwas wie”). Wichtige, aber verwirrende Details wie die richtige Fehlerbehandlung wurden dem Leser als Übung überlassen. Was “doppelte Klammern” betrifft, bin ich mir nicht sicher, was das ist oder wovon Sie sprechen. Für mich ist das eine “Klammer”. { Charakter. Ich weiß nicht, was eine “Doppelklammer” ist. Vielleicht haben Sie ein Problem mit der Schriftart?

    – TED

    25. August 2015 um 12:54 Uhr

1647107411 670 Wie ersetzt man alle Vorkommen eines Zeichens in einer Zeichenfolge
Volomike

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

while(sHaystack.find(sNeedle) != std::string::npos) {
  sHaystack.replace(sHaystack.find(sNeedle),sNeedle.size(),sReplace);
}

  • Dies ist zwar wahrscheinlich eine geeignete Lösung, wenn die Anzahl der zu ersetzenden Zeichen im Vergleich zur Länge der Zeichenfolge klein ist, aber es lässt sich nicht gut skalieren. Wenn der Anteil der zu ersetzenden Zeichen in der ursprünglichen Zeichenfolge zunimmt, nähert sich diese Methode zeitlich O(N^2).

    – und und

    24. Mai 2010 um 14:37 Uhr

  • Wahr. Meine allgemeine Philosophie ist es, das Einfache (zu schreiben und zu lesen) zu tun, bis die Ineffizienzen echte Probleme verursachen. Es gibt einige Umstände, in denen Sie möglicherweise riesige Saiten haben, bei denen O (N ** 2) wichtig ist, aber in 99% der Fälle sind meine Saiten 1K oder weniger.

    – TED

    25. Mai 2010 um 3:40 Uhr

  • … davon abgesehen gefällt mir Kirills Methode besser (und hatte sie bereits positiv bewertet).

    – TED

    25. Mai 2010 um 3:41 Uhr

  • Was passiert, wenn “x” nicht gefunden wird? Und warum verwendest du doppelte Klammern?

    – Prasath Govind

    25. August 2015 um 11:26 Uhr

  • @PrasathGovind – Ich habe nur die erforderlichen Anrufe angezeigt (daher “so etwas wie”). Wichtige, aber verwirrende Details wie die richtige Fehlerbehandlung wurden dem Leser als Übung überlassen. Was “doppelte Klammern” betrifft, bin ich mir nicht sicher, was das ist oder wovon Sie sprechen. Für mich ist das eine “Klammer”. { Charakter. Ich weiß nicht, was eine “Doppelklammer” ist. Vielleicht haben Sie ein Problem mit der Schriftart?

    – TED

    25. August 2015 um 12:54 Uhr

1647107411 233 Wie ersetzt man alle Vorkommen eines Zeichens in einer Zeichenfolge
Adrià Arrufat

Der Vollständigkeit halber, hier ist, wie man es mit macht std::regex.

#include <regex>
#include <string>

int main()
{
    const std::string s = "example string";
    const std::string r = std::regex_replace(s, std::regex("x"), "y");
}

994660cookie-checkWie ersetzt man alle Vorkommen eines Zeichens in einer Zeichenfolge?

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

Privacy policy