2013-04-08 17 views
5

Mam problem z boost::regex::regex_match. Pracuję z włączonym BOOST_REGEX_MATCH_EXTRA.Zwiększ wyrażenie regularne. Nazwana grupa w dwóch częściach


Co mam:

(jest to prosty przykład mój problem, a nie prawdziwe zadanie)

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

Co chcę uzyskać:

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

regex:

(to działa poprawnie)

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

OUTPUT1: what["group"]=5 i what["group"].captures()= [3, 4, 5]

OUTPUT2: not matched

p roblem to:

Potrzebuję zebrać dane z więcej niż jeden część regex do jednej grupy.

Próbowałem:

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

OUTPUT1: what["group"]=4 i what["group"].captures()=[3, 4]

output2: not matched

OK, rozumiem. Nie widzi drugiej deklaracji grupy.

Próbowałem:

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

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

output2: not matched

  • Ale co to? Gdzie jest drugie 4? Sprawdza wzór "grupy", ponieważ pierwszy przykład pasuje, ale drugi nie. Ale podwaja ostatnią znalezioną wartość zamiast zapisywać nową. Czemu? Może zapomniałem włączyć flagi?
  • Czy istnieje inny sposób na uzyskanie danych z jednej grupy z innej części wyrażenia regularnego?

mam więcej niż jedną grupę, tak token_iterator nie może mi pomóc.

Wyrażenie należy skonfigurować w pliku konfiguracyjnym. nie można użyć statycznego Xpressive.

+1

Nie, nie można nadziać dwa różne części łańcucha jednej grupy docelowej do przechwytywania - przynajmniej nie bez jednoczesnego przechwytywania wszystko pomiędzy. –

Odpowiedz

0

ten sposób interpretować swój problem:

String: Total price: $1,234

i chcesz uchwycić koszty jako 1234 (bez przecinka)

Nie jest to możliwe tylko z regex , ponieważ nie ma sposobu na uchwycenie grupy i wykluczenie części w środku. Biorąc to pod uwagę, możesz użyć 2 grup dopasowania i wcześniejszych, a następnie wewnątrz kodu zszyć grupy. W powyższym przykładzie, jeśli nie wiem, czy będzie przecinek czy nie (czyli cena waha się od 1-5000) można zrobić coś takiego

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

który odpowiada 1-3 cyfr, a następnie szukaj przecinka, a jeśli istnieje, użyj innej grupy nazw i dopasuj drugą porcję.

Oto naprawdę miły źródłem dla badań regex: www.regex101.com

+0

Oczywiście, mogę to zrobić z kodem dodawania. Co więcej, z kodem dodawania mogę to zrobić bez regex. Ale chcę zapisać regex do pliku konfiguracyjnego. Ale nie jest tak łatwo stworzyć taki kod dodający, który będzie działał z DOWOLNYM niezmienionym wyrażeniem regularnym. Nie wiem, ile grup (cena, cena2, cena3 ...) będzie iw jakiej kolejności. – Darida

+0

@Darida Pracuję teraz nad podobną sprawą. Moje obecne rozwiązanie polega na tym, że w pliku konfiguracyjnym przechowuję nie tylko wzór regex, ale także "opis wartości". Zasadniczo jest to tylko sekwencja przechwytywania nazw grup i arbitralnych ciągów. Kod dopasowuje ciąg do wzorca, a jeśli się powiedzie, buduje wartość rzeczywistą w oparciu o "opis wartości" łączący wspomniane grupy przechwytywania i to, co zostało określone. Pozwala to na rozsądną elastyczność w plikach konfiguracyjnych przy jednoczesnym zachowaniu stałego kodu. –