2015-04-29 4 views
6

Ich brauche eine Regex, die ein Argument zwischen Klammern erfasst. Die Leerzeichen vor und nach dem Argument sollten nicht erfasst werden. Zum Beispiel sollte "(ab & c)""ab & c" zurückgeben. Das Argument kann in einfache Anführungszeichen eingeschlossen werden, wenn führende oder nachfolgende Leerzeichen benötigt werden. Also, "(' ab & c ')" sollte " ab & c " zurückgeben.Fehler in VS13 Regex: falsche Reihenfolge für Alternativen?

Es scheint, dass die zweite Alternative abgestimmt, aber es nahm auch den Platz vor dem ersten Zitat! Es sollte von der \s nach der öffnenden Klammer gefangen worden sein.

die zweite Alternative ausbauen:

regex_match(String, Matches, wregex(L"\\(\\s*(?:'(.+)')\\s*\\)")); 
wcout << L"<" + Matches[1].str() + L">" + L"\n"; 
// Results in "< ab & c >", OK 

es eine Erfassungsgruppe von Alternativen zu machen:

regex_match(String, Matches, wregex(L"\\(\\s*('(.+)'|(.+?))\\s*\\)")); 
wcout << L"<" + Matches[1].str() + L"> " + L"<" + Matches[2].str() + L"> " + L"<" + Matches[3].str() + L">" + L"\n"; 
// Results in "<' ab & c '> < ab & c > <> ", OK 

Bin ich etwas mit Blick auf?

+0

Ein seltsames Verhalten. Haben Sie versucht, die Punkte durch '[^ ']' zu ersetzen, um zu sehen, was passiert? Und hast du versucht, dasselbe ohne wchar_t zu machen? (Beachten Sie, dass die ecmascript Regex Engine mit Multibyte-Zeichen nicht sehr flüssig ist) –

+0

Sehr interessanter Effekt - in g ++ mit libstdC++ funktioniert es wie in VS2013, aber ohne Leerzeichen am Anfang. In clang ++ mit libC++ wird die erste Gruppe gefunden. Es gibt also 3 verschiedene Verhaltensweisen für 3 Standard-Bibliotheken :) regexr.com (ich glaube, Javascript-Variante) denkt, dass libC++ korrekt ist. – Predelnik

+0

@ Casimir: dasselbe Problem mit "normalen" Zeichen; Ersetzen Sie die Punkte mit '[^ ']' macht es aber funktioniert. @Predenik: Meiner Meinung nach sollte die erste Gruppe übereinstimmen, ich habe die Frage gepostet, weil ich aus Erfahrung weiß, wie leicht man mit Regexen Fehler macht ... –

Antwort

1

Hier ist mein Vorschlag, dass zwei Alternativen in 1 verschmilzt:

wstring String = L"(' ab & c ')"; 
wsmatch Matches; 
regex_match(String, Matches, wregex(L"\\(\\s*(')?([^']+)\\1\\s*\\)")); 
wcout << L"<" + Matches[2].str() + L"> " + L"\n"; 

Die \(\s*(')?([^']+)\1\s*\) regex einen Rückverweis verwendet, um sicherzustellen, dass wir ein ' am Anfang und das Ende, um 'something zu erfassen haben nicht . Der Wert wird in Gruppe gefangen 2.

Ausgang:

enter image description here

+0

Funktioniert es für Sie oder benötigen Sie weitere Unterstützung? –

+0

funktioniert gut, danke. –