2015-04-29 11 views
6

Potrzebuję wyrażeń regularnych, które przechwytują argumenty między nawiasami. Puste przed argumentem i po nim nie powinny zostać przechwycone. Na przykład: "(ab & c)" powinien zwrócić "ab & c". Argument może być ujęty w pojedyncze cudzysłowy, jeśli potrzebne są początkowe lub końcowe spacje. Tak więc, "(' ab & c ')" powinien zwrócić " ab & c ".Błąd w reseksie VS13: niewłaściwa kolejność dla alternatyw?

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

Wygląda na to, że druga alternatywa się zgadza, ale zajęła również miejsce przed pierwszym cytatem! Powinien zostać przechwycony przez \s po nawiasie otwierającym.

Zdejmowanie drugą alternatywę:

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

czyni go grupa przechwytywanie Alternatywy:

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 

jestem widokiem coś?

+0

dziwne zachowanie. Czy próbowałeś zamienić kropki na '[^ ']', aby zobaczyć, co się dzieje? Czy próbowałeś zrobić to samo bez wchar_t? (zauważ, że silnik wyrażeń regularnych ecmascript nie jest bardzo płynny w przypadku znaków wielobajtowych) –

+0

Bardzo ciekawy efekt - w g ++ z libstdC++ działa tak jak w VS2013, ale bez spacji na początku. W clang ++ z libC++ pierwsza grupa jest dopasowana. A więc 3 różne zachowania dla 3 standardowych bibliotek :) regexr.com (wierzę w wariant javascript) uważa, że ​​libC++ jest poprawne. – Predelnik

+0

@asimimir: ten sam problem z "normalnymi" znakami; zamiana kropek na '[^ ']' sprawia, że ​​działa. @Predenik: Moim zdaniem pierwsza grupa powinna być dopasowana, napisałem pytanie, bo wiem z doświadczenia, jak łatwo popełnia się błędy z wyrażeń regularnych ... –

Odpowiedz

1

Oto moja propozycja, która łączy dwie alternatywy do 1:

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

\(\s*(')?([^']+)\1\s*\) regex używa kopii odwołania, aby upewnić się, że mamy ' na początku i końca, aby nie uchwycić 'something . Wartość jest złapany w grupie 2.

wyjściowa:

enter image description here

+0

Czy to działa dla Ciebie, czy potrzebujesz dodatkowej pomocy? –

+0

działa dobrze, dzięki. –

Powiązane problemy