2012-06-11 12 views
28

muszę podzielić ciągRegex z -, ::, (i)

(age-is-25 :: LUB :: LAST_NAME-is-QA6) :: I: :(wiekiem oznacza OR 20 :: :: zawiera FIRST_NAME-test)

do

ciąg [0] = (wiekiem oznacza 25 OR :: :: nazwisko_abonenta-is-QA6)

string [1] = AND

string [2] = (wiek-is-20 :: :: first_name-OR zawiera test)

Próbowałem pisać tak wiele wyrażeń regex, ale nic nie działa zgodnie z oczekiwaniami.

Korzystając z następującego wyrażenia regularnego, Matcher.groupCount() zwraca 2, ale przypisanie wyników do listy tablic zwraca jako dane wartości null.

Wzór wzorca = Pattern.compile ("(\\): :)? | (:: \\()?");

próbowałem podzielić go używając) :: czyli. :(

wiem regex wygląda zbyt głupi, ale jako początkujący to najlepiej mógłbym napisać

+3

Uogólnienie tego problemu jest odpowiednikiem wyrażenia analizowania z regexp, co nie jest możliwe: regex nie jest wystarczająco silny do tego. – dasblinkenlight

+8

To nie jest głupie, jeśli faktycznie próbowałeś czegoś :) Świetna robota za wypróbowanie czegoś najpierw przed pytaniem. – Ewald

+0

jak to może być podzielone przez '::' tylko wokół 'ORAZ 'bez umieszczania tego' ORAZ 'w tym splitter? – dantuch

Odpowiedz

36

Możesz użyć dodatnich przodków wyprzedzających i lookbehind, aby dopasować pierwszy i ostatni nawias.

String str = "(age-is-25::OR::last_name-is-qa6)::AND::(age-is-20::OR::first_name-contains-test)"; 

for (String s : str.split("(?<=\\))::|::(?=\\()")) 
    System.out.println(s); 

Wyjścia:

(age-is-25::OR::last_name-is-qa6) 
AND 
(age-is-20::OR::first_name-contains-test) 

Tylko uwaga jednak: Wydaje się, że jesteś parsowania jakiegoś języka rekurencyjnego. Wyrażenia regularne nie nadają się do tego. W przypadku zaawansowanego analizowania zaleca się zapoznanie z innymi metodami analizowania.

+8

Zabawne, jak to jest pierwszy odbierający, który nie robi dzikiego zgadywania. Jest wyraźnie bardziej zaznajomiony z zaawansowanym regexem i nadal testuje, reszta jest jak "spróbuj tego, a jeśli masz szczęście, to zadziała". – MarioDS

+1

@dacwe naprawdę jeden z mądrych kolegów z odpowiedzi. +1 do niego –

+0

@dacwe: Wielkie dzięki! Btw, robię nt zrozumieć użycie? <= i? = w regex. Nigdy nie widziałem tych w żadnych tutoriali. Czy możesz wyjaśnić, czy możesz wskazać jakiś adres URL, skąd mogę uzyskać informacje na ten temat? Dzięki jeszcze raz. – aradhak

-1
textString.split("\\)::|::\\(") 
.

powinno działać.

+0

backslash przychodzi dwa razy ... nie wiem dlaczego formatowanie usuwa mój drugi ukośnik odwrotny – ManojGumber

+3

Jeśli formatowanie zepsuło twój kod, uczyń go blokiem kodu, lub użyj '' 'tych' takich jak ten ' – dantuch

+0

Nie będzie zawierało znaków) w pierwszym łańcuchu znaków i (w 3 ciąg –

-1

ten powinien pracować dla Ciebie.

\)::|::\(
1

Dla mnie wygląda na to, że duża część stresu pochodzi z potrzeby unikania znaków specjalnych w wyszukiwaniu. Gorąco polecam, aby nie robić ręcznego wybierania znaków specjalnych, ale zamiast tego używać Pattern.quote(...) dla ucieczki.

1

Powinno to działa

"(?<=\\))::|::(?=\\()"