2012-07-16 17 views
12

Ich versuche, bestimmte Muster in einer Zeichenfolge mit verschiedenen Ersatzmuster zu ersetzen.Bedingte ersetzen Regex übereinstimmt in Zeichenfolge

Beispiel:

string test = "test replacing \"these characters\""; 

Was ich will, ist, alles zu tun, ersetzen ‚‘ mit ‚_‘ und alle anderen nicht Buchstaben oder eine Zahl Zeichen mit einem leeren String. Ich habe die folgende Regex erstellt und es scheint, richtig zu tokenisieren, aber ich bin nicht sicher, wie man (wenn möglich) eine bedingte Ersetzung unter Verwendung regex_replace durchführt.

string test = "test replacing \"these characters\""; 
regex reg("(\\s+)|(\\W+)"); 

erwartetes Ergebnis nach ersetzen wäre:

string result = "test_replacing_these_characters"; 

EDIT: Ich kann nicht boost, weshalb ich es aus den Tags links. Also bitte keine Antwort, die Boost beinhaltet. Ich muss dies mit der Standardbibliothek tun. Es kann sein, dass eine andere Regex das Ziel erreichen würde oder dass ich gerade zwei Passagen machen würde.

EDIT2: Ich erinnerte mich nicht, welche Zeichen in \w zur Zeit meiner ursprünglichen Regex enthalten waren, nachdem ich es nachgeschlagen habe, habe ich den Ausdruck weiter vereinfacht. Wiederum ist das Ziel, dass alle passenden \ s + durch '_' ersetzt werden sollen und alles, was zu \ W + passt, sollte durch eine leere Zeichenfolge ersetzt werden.

+0

Warum fallen Sie das letzte '" '-char in Ihrem Beispiel Ausgabe –

+0

@rubberboots - weil nur Leerraum sollte mit einem Unterstrich, jede andere nicht Buchstaben und Ziffer ersetzt werden Charakter sollte mit nichts ersetzt werden – pstrjds

+0

Ich sehe, so dass Sie verschiedene Ersatztexte in einem Durchgang haben wollen.A funktioniert nicht in C++ Regex.Wenn jemand einen Trick dafür, möchte ich das verwenden auch ;-) –

Antwort

21

Die C++ (0x, 11, tr1) regulären Ausdrücke do not really work (stackoverflow) in jedem Fall (schauen Sie die phrase regex on this page für gcc), so ist es besser, use boost für eine Weile.

Sie können versuchen, wenn Sie Compiler die regulären Ausdrücke benötigt unterstützt:

#include <string> 
#include <iostream> 
#include <regex> 

using namespace std; 

int main(int argc, char * argv[]) { 
    string test = "test replacing \"these characters\""; 
    regex reg("[^\\w]+"); 
    test = regex_replace(test, reg, "_"); 
    cout << test << endl; 
} 

Die oben genannten Arbeiten in Visual Studio 2012Rc.

Edit 1: Von zwei verschiedenen Saiten in einem Durchgang (je nach Spiel) zu ersetzen, würde ich denke, das hier nicht funktioniert. In Perl könnte dies leicht innerhalb ausgewerteter Ersatzausdrücke (/e Switch) erfolgen.

Daher werden Sie zwei Pässe benötigen, wie Sie vielleicht schon vermutet:

... 
string test = "test replacing \"these characters\""; 
test = regex_replace(test, regex("\\s+"), "_"); 
test = regex_replace(test, regex("\\W+"), ""); 
... 

Edit 2:

Wenn es möglich wäre, eine Callback-Funktiontr() in regex_replace zu verwenden, dann könnten Sie die Substitution dort ändern, wie zum Beispiel:

string output = regex_replace(test, regex("\\s+|\\W+"), tr); 

mit tr() dabei die Austauscharbeit:

string tr(const smatch &m) { return m[0].str()[0] == ' ' ? "_" : ""; } 

das Problem gelöst worden wäre. Leider gibt es keine solche Überlastung in einigen C++ 11 Regex-Implementierungen, aber Boost has one.Im Folgenden würde mit Boost arbeiten und einen Durchlauf verwenden:

... 
#include <boost/regex.hpp> 
using namespace boost; 
... 
string tr(const smatch &m) { return m[0].str()[0] == ' ' ? "_" : ""; } 
... 

string test = "test replacing \"these characters\""; 
test = regex_replace(test, regex("\\s+|\\W+"), tr); // <= works in Boost 
... 

Vielleicht eines Tages arbeiten mit C++ oder was auch immer Zahl als nächstes kommt.

Grüße

RBO

+0

Ich möchte nicht ersetzen "mit Unterstrich, sollte es durch nichts ersetzt werden. Das ist der Kern meines Problems, ich möchte die erste Match-Gruppe durch _ ersetzen und die zweite Match-Gruppe mit leeren String. Ich sollte auch haben erwähnt, dass ich boost nicht verwenden kann. – pstrjds

+0

Ihre zweite Bearbeitung, die in VS2012 ausgeführt wird, löst noch nicht mein Problem.Das Leerzeichen muss mit _ ersetzt werden und alle anderen nicht Buchstaben und Ziffern müssen durch leere Zeichenfolge ersetzt werden – pstrjds

+0

Die Two-Pass-Version tut Dies auf meinem System ist das Ergebnis "test_replacing_these_characters". –

Verwandte Themen