@poly Ich würde denken, dass dies auch für C ++ gefragt worden sein muss, aber ich kann es nicht finden
Michael Mrozek
1
Es gibt ein Standard-Tag zu dieser Frage, aber vielleicht interessieren Sie sich auch für die String-Algorithmen von boost, die auch eine große Auswahl an Ersetzungsalgorithmen enthalten (Inplace / Copy, Groß- / Kleinschreibung beachten / Groß- und Kleinschreibung nicht beachten, First / Last / All / n-th ersetzen ).
Es gibt eine Funktion zum Suchen eines Teilstrings in einem String ( find) und eine Funktion zum Ersetzen eines bestimmten Bereichs in einem String durch einen anderen String ( replace), sodass Sie diese kombinieren können, um den gewünschten Effekt zu erzielen:
Wie würde ich das beheben, wenn die ursprüngliche Zeichenfolge mehr als eine Instanz von "$ name" hätte und ich alle ersetzen wollte?
Tom Leese
1
Warum nicht fromund topro weitergegeben constReferenz? Was funktioniert, wenn fromes nicht da ist? -1von mir dafür.
sbi
10
@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, constund wenn ich eine solche Dienstprogrammmethode schreiben würde, würde ich sie nur aufrufen, wenn ich das wüsste Ersatz waren gültig
Michael Mrozek
10
@ Michael: Gut, ich habe meine Abwertung in eine Aufwärtsabstimmung verwandelt. Das Ablehnen constignoriert eines der besten Tools von C ++. Das Übergeben pro constReferenz sollte der Standardmodus für Funktionsparameter sein. (FTR, ohne das constkönnten Sie nicht einmal String-Literale an Ihre Funktion übergeben, da Sie Temporäre nicht an Nicht- constReferenzen binden können . Die Funktion würde also nicht einmal das tun, wofür sie geschrieben wurde.)
sbi
19
Ist dies noch die einzige Lösung im Jahr 2018? Wenn dies der Fall ist und ein C ++ - Komitee dies liest, klären Sie es. Es ist peinlich. Bitte teilen (String, String) und ersetzen (String, String)!
user997112
95
Mit C ++ 11 können Sie std::regexwie folgt verwenden:
Ich bin mir ziemlich sicher std::regex_replace, dass Qts String nicht akzeptiert wird.
BartoszKP
1
Du hast recht. Wie es passiert, bietet QString eine Ersetzungsmethode, die ein QRexExp akzeptiert und es ermöglicht, Qts eigenes Material zu verwenden. Aber ich denke , die aktuelle Antwort durch Ersetzen korrigiert werden kann stringmit string.toStdString().
Tom
1
Oder einfach durch Wechseln Stringzu std::string, weil die Frage nicht mit Qt zusammenhängt. Bitte denken Sie darüber nach - ich werde Ihre Antwort danach gerne positiv bewerten.
BartoszKP
5
Raw String ermöglicht das Schreiben R"(\$name)"anstelle von "\\$name".
Jarod42
2
Wie viel langsamer ist dies als Suchen / Ersetzen ohne Berücksichtigung der Konstruktionszeit von std :: regex?
jw_
18
std::stringhat eine replaceMethode, ist es das, wonach Sie suchen?
Wenn Sie Leistung benötigen, finden Sie hier eine optimierte Funktion, mit der die Eingabezeichenfolge geändert wird. Es wird keine Kopie der Zeichenfolge erstellt:
Ihr Aufruf von subject.replace in ReplaceStringInPlace () ändert das wirklich die Zeichenfolge inplace?
Damian
Ich habe kurz auf die Quelle geschaut und es sieht so aus, als würde die Bewegungssemantik verwendet, um die Vorderseite der alten Zeichenfolge an ihren Platz zu verschieben, sodass diese nicht kopiert wird, sondern das neu eingefügte Stück in die alte Zeichenfolge und den Schwanz der alten Zeichenfolge kopiert wird wird in die Größe des Puffers der alten Zeichenfolge kopiert. Es ist möglich, dass die Zeichenfolge so stark erweitert wird, dass der gesamte zugrunde liegende Puffer neu zugewiesen wird. Wenn Sie jedoch 1 zu 1 wie in seinem Beispiel ersetzen, geschieht dies meiner Meinung nach "an Ort und Stelle" oder ohne Kopieren. Wenn Sie die Zeichenfolge jedoch erweitern, Nur der erste Teil der alten Zeichenfolge wird nicht kopiert, und vielleicht erst dann.
Motes
6
Ja, Sie können dies tun, aber Sie müssen die Position der ersten Zeichenfolge mit dem Element find () der Zeichenfolge ermitteln und dann durch das Element replace () ersetzen.
Wenn Sie die Standardbibliothek verwenden möchten, sollten Sie sich unbedingt eine Kopie des Buches besorgen The C ++ Standard Library das all diese Dinge sehr gut abdeckt.
Es wird wiederholt aufgerufen std::string::find(), um andere Vorkommen der gesuchten Zeichenfolge zu lokalisieren, bis std::string::find()nichts mehr gefunden wird. Da std::string::find()die Position der Übereinstimmung zurückgegeben wird, besteht kein Problem darin, Iteratoren ungültig zu machen.
Sie könnten dies in eine Funktion einschließen, aber diese einzeilige Lösung klingt akzeptabel. Das Problem ist, dass dies nur das erste Vorkommen ändert. Möglicherweise möchten Sie eine Schleife darüber ausführen, aber Sie können auch mehrere Variablen mit demselben Token in diese Zeichenfolge einfügen ( %s)
Wie der Stil, fand aber die verschiedenen Saiten verwirrend ^^str.replace(str.find("%s"), string("%s").size(), "Something");
Paul Würtz
3
Wenn alle Zeichenfolgen std :: string sind, treten bei der Verwendung merkwürdige Probleme mit dem Abschneiden von Zeichen auf, sizeof()da diese für C-Zeichenfolgen und nicht für C ++ - Zeichenfolgen bestimmt sind. Das Update besteht darin, die .size()Klassenmethode von zu verwenden std::string.
wstring myString = L"Hello $$ this is an example. By $$.";
wstring search = L"$$";
wstring replace = L"Tom";for(int i = myString.find(search); i >=0; i = myString.find(search))
myString.replace(i, search.size(), replace);
Wenn Sie es schnell erledigen möchten, können Sie einen Zwei-Scan-Ansatz verwenden. Pseudocode:
erste Analyse. Finde heraus, wie viele passende Zeichen es gibt.
Erweitern Sie die Länge der Zeichenfolge.
zweite Analyse. Beginnen Sie am Ende der Zeichenfolge, wenn wir eine Übereinstimmung erhalten, die wir ersetzen. Andernfalls kopieren wir einfach die Zeichen aus der ersten Zeichenfolge.
Ich bin mir nicht sicher, ob dies zu einem In-Place-Algo optimiert werden kann.
Und ein C ++ 11-Codebeispiel, aber ich suche nur nach einem Zeichen.
Ich lerne gerade C ++, aber wenn ich einen Teil des zuvor veröffentlichten Codes bearbeite, würde ich wahrscheinlich so etwas verwenden. Dies gibt Ihnen die Flexibilität, eine oder mehrere Instanzen zu ersetzen, und Sie können auch den Startpunkt angeben.
Antworten:
Es gibt eine Funktion zum Suchen eines Teilstrings in einem String (
find
) und eine Funktion zum Ersetzen eines bestimmten Bereichs in einem String durch einen anderen String (replace
), sodass Sie diese kombinieren können, um den gewünschten Effekt zu erzielen:Als Antwort auf einen Kommentar
replaceAll
würde ich wahrscheinlich ungefähr so aussehen:quelle
from
undto
pro weitergegebenconst
Referenz? Was funktioniert, wennfrom
es nicht da ist?-1
von mir dafür.const
und wenn ich eine solche Dienstprogrammmethode schreiben würde, würde ich sie nur aufrufen, wenn ich das wüsste Ersatz waren gültigconst
ignoriert eines der besten Tools von C ++. Das Übergeben proconst
Referenz sollte der Standardmodus für Funktionsparameter sein. (FTR, ohne dasconst
könnten Sie nicht einmal String-Literale an Ihre Funktion übergeben, da Sie Temporäre nicht an Nicht-const
Referenzen binden können . Die Funktion würde also nicht einmal das tun, wofür sie geschrieben wurde.)Mit C ++ 11 können Sie
std::regex
wie folgt verwenden:Der doppelte Backslash ist erforderlich, um einem Escape-Zeichen zu entkommen.
quelle
std::regex_replace
, dass Qts String nicht akzeptiert wird.string
mitstring.toStdString()
.String
zustd::string
, weil die Frage nicht mit Qt zusammenhängt. Bitte denken Sie darüber nach - ich werde Ihre Antwort danach gerne positiv bewerten.R"(\$name)"
anstelle von"\\$name"
.std::string
hat einereplace
Methode, ist es das, wonach Sie suchen?Du könntest es versuchen:
Ich habe es nicht selbst versucht, lese einfach die Dokumentation auf
find()
undreplace()
.quelle
Verwenden Sie Folgendes, um die neue Zeichenfolge zurückzugeben:
Wenn Sie Leistung benötigen, finden Sie hier eine optimierte Funktion, mit der die Eingabezeichenfolge geändert wird. Es wird keine Kopie der Zeichenfolge erstellt:
Tests:
Ausgabe:
quelle
Ja, Sie können dies tun, aber Sie müssen die Position der ersten Zeichenfolge mit dem Element find () der Zeichenfolge ermitteln und dann durch das Element replace () ersetzen.
Wenn Sie die Standardbibliothek verwenden möchten, sollten Sie sich unbedingt eine Kopie des Buches besorgen The C ++ Standard Library das all diese Dinge sehr gut abdeckt.
quelle
Ich benutze im Allgemeinen Folgendes:
Es wird wiederholt aufgerufen
std::string::find()
, um andere Vorkommen der gesuchten Zeichenfolge zu lokalisieren, bisstd::string::find()
nichts mehr gefunden wird. Dastd::string::find()
die Position der Übereinstimmung zurückgegeben wird, besteht kein Problem darin, Iteratoren ungültig zu machen.quelle
Das klingt nach einer Option
string.replace(string.find("%s"), string("%s").size(), "Something");
Sie könnten dies in eine Funktion einschließen, aber diese einzeilige Lösung klingt akzeptabel. Das Problem ist, dass dies nur das erste Vorkommen ändert. Möglicherweise möchten Sie eine Schleife darüber ausführen, aber Sie können auch mehrere Variablen mit demselben Token in diese Zeichenfolge einfügen (
%s
)quelle
str.replace(str.find("%s"), string("%s").size(), "Something");
Wenn alle Zeichenfolgen std :: string sind, treten bei der Verwendung merkwürdige Probleme mit dem Abschneiden von Zeichen auf,
sizeof()
da diese für C-Zeichenfolgen und nicht für C ++ - Zeichenfolgen bestimmt sind. Das Update besteht darin, die.size()
Klassenmethode von zu verwendenstd::string
.Das ersetzt sHaystack inline - es ist nicht erforderlich, eine = Zuweisung vorzunehmen.
Anwendungsbeispiel:
quelle
quelle
Wenn Sie es schnell erledigen möchten, können Sie einen Zwei-Scan-Ansatz verwenden. Pseudocode:
Ich bin mir nicht sicher, ob dies zu einem In-Place-Algo optimiert werden kann.
Und ein C ++ 11-Codebeispiel, aber ich suche nur nach einem Zeichen.
quelle
quelle
Meine eigene Implementierung, bei der berücksichtigt wird, dass die Größe der Zeichenfolge nur einmal geändert werden muss, kann dann ersetzt werden.
Die Verwendung könnte beispielsweise so sein:
quelle
Ich lerne gerade C ++, aber wenn ich einen Teil des zuvor veröffentlichten Codes bearbeite, würde ich wahrscheinlich so etwas verwenden. Dies gibt Ihnen die Flexibilität, eine oder mehrere Instanzen zu ersetzen, und Sie können auch den Startpunkt angeben.
quelle
Dies könnte noch besser zu bedienen sein
quelle