2013-04-08 10 views
5

Ich habe ein Problem mit boost::regex::regex_match. Ich arbeite mit eingeschaltet BOOST_REGEX_MATCH_EXTRA.Boost Regex. Benannte Gruppe in zwei Teilen


Was ich habe:

(dies ist ein einfaches Beispiel für mein Problem, nicht eine echte Aufgabe)

string input1= "3 4 5"; 
string input2= "3 4 7"; 

Was ich zu bekommen:

list output1= [3 4 5]; 
list output2= []; //not matched 

regex:

(dies ok arbeitet)

((?<group>[0-6])[ ]?)* 

output1: what["group"]=5 und what["group"].captures()= [3, 4, 5]

output2: not matched

Der p Problem ist:

Ich muss Daten von mehr als eine Teil von Regex zu einer Gruppe sammeln.

Ich habe versucht:

((?<group>[0-6])[ ])*(?<group>[0-6]) 

output1: what["group"]=4 und what["group"].captures()=[3, 4]

output2: not matched

OK, ich verstehe. Es wird keine zweite Gruppenerklärung angezeigt.

Ich habe versucht:

((?<group>[0-6])[ ])*(?&group) 

output1: what["group"]=4 und what["group"].captures()= [3, 4, 4]

output2: not matched

  • Aber was dieses? Woher kommt die zweite 4? Es überprüft das "Gruppen" -Muster, weil das erste Beispiel übereinstimmt, das zweite jedoch nicht. Aber es verdoppelt den zuletzt gefundenen Wert, anstatt neu zu speichern. Warum? Vielleicht habe ich vergessen, ein paar Flaggen zu drehen?
  • Und gibt es eine andere Möglichkeit, in einer Gruppe Daten aus verschiedenen Teilen von Regex-Ausdruck zu bekommen?

Ich habe mehr als eine Gruppe, so token_iterator kann mir nicht helfen.

Und Ausdruck sollte in der Konfigurationsdatei konfiguriert werden. Statisches Xpressive kann nicht verwendet werden.

+1

Nein, Sie nicht zwei verschiedene Teile einer Zielzeichenfolge in einer Capture-Gruppe stopfen kann - ohne auch zumindest nicht alles zwischen einzufangen. –

Antwort

0

Dies ist, wie ich Ihr Problem interpretieren:

String: Total price: $1,234

und Sie wollen die Kosten als 1234 (ohne Komma) mit nur regex

Dies ist nicht möglich, erfassen, , da es keine Möglichkeit gibt, eine Gruppe zu erfassen und Teile in der Mitte auszuschließen. Davon abgesehen können Sie 2 Match-Gruppen und Lookaheads verwenden und dann die Gruppen innerhalb des Codes zusammenheften. Im obigen Beispiel, wenn Sie nicht wissen, ob es ein Komma oder nicht (dh Preisklassen 1-5000) Sie so etwas wie

Total price: \$(?P<price>\d{1,3})(?:(?=\,),(?P<price2>\d{3})|)

tun kann, die 1-3 Ziffern übereinstimmt, dann Suchen Sie nach einem Komma, und wenn es existiert, verwenden Sie eine andere Namensgruppe und stimmen Sie mit dem zweiten Teil überein.

Hier ist eine wirklich schöne Ressource für regex Test: www.regex101.com

+0

Natürlich kann ich dies mit Zusatzcode tun. Mit Additionscode kann ich das auch ohne Regex machen. Aber ich möchte regex in der Konfigurationsdatei speichern. Aber es ist nicht so einfach, einen solchen Zusatzcode zu erstellen, der mit ANY UNKNOWN Regex funktioniert. Ich weiß nicht, wie viele Gruppen (Preis, Preis2, Preis3 ...) es gibt und in welcher Reihenfolge – Darida

+0

@Darida Ich arbeite jetzt an einem ähnlichen Fall. Meine derzeitige Lösung ist, dass ich in der Konfigurationsdatei nicht nur das Regex-Muster, sondern auch die "Wertbeschreibung" behalte. Im Grunde genommen ist es nur eine Sequenz zum Erfassen von Gruppennamen und willkürlichen Strings. Der Code vergleicht string mit dem Muster, und wenn er erfolgreich ist, baut er den tatsächlichen Wert auf der Grundlage dieser "Wertbeschreibung" auf, die die erwähnten einfangenden Gruppen verkettet und was auch immer spezifiziert ist. Dies ermöglicht eine angemessene Flexibilität in der Konfigurationsdatei, während immer noch fester Code dahinter ist. –