2012-10-14 9 views
9

Powiel możliwe:
Split a String based on regexPodział ciąg wszystkich pomieszczeniach z wyjątkiem tych, w nawiasach

nigdy nie był regularny guru wypowiedzi, więc potrzebuję waszej pomocy! Mam ciąg tak:

String s = "a [b c] d [e f g]"; 

Chcę podzielić ten ciąg używając spacji jako ograniczników - ale nie chcę, aby podzielić na przestrzenie, które pojawiają się w nawiasach []. Zatem z powyższego przykładu, chciałbym tej tablicy:

{"a", "[b c]", "d", "[e f g]"} 

Wszelkie porady na co regex może być stosowany w połączeniu z split w celu osiągnięcia tego celu?


Oto kolejny przykład:

"[a b] c [[d e] f g]" 

staje

{"[a b]", "c", "[[d e] f g]"} 
+3

[Lekcja: Regular Expressions] (http://docs.oracle.com/javase/tutorial/essential/regex/) – user1329572

+3

Czy gniazdo nawiasy? – artbristol

+1

@artbristol bardzo dobry komentarz. – Juvanis

Odpowiedz

9

myślę, że to powinno działać, wykorzystując negative lookahead - pasuje bez spacji, która pochodzi przed zamknięciem wspornik bez wspornika otwarcia:

"a [b c] d [e f g]".split("\\s+(?![^\\[]*\\])"); 

Dla zagnieżdżonych nawiasów trzeba będzie napisać parser, Wyrażenia regularne can nie stać na nieskończony poziom i stają się zbyt skomplikowane na więcej niż jednym lub dwóch poziomach. Mój wyraz na przykład zawiedzie

"[a b [c d] e] f g" 
+2

Nie kompiluje - otrzymuję "zniekształcone wyrażenie regularne" błąd – alfasin

+0

Hm, czy java potrzebuje '[' aby uciec w klasie postaci? Dzięki za podpowiedź – Bergi

+0

to działa dobrze dla mnie. – Jimmy

0

Gdybym zrozumiał swoje pytanie poprawnie to może być odpowiedź jest następująca rule4.

rule1 -> ((a-z).(\w))*.(a-z) 

rule2 -> ([).rule1.(]) 

rule3 -> ([).(rule1.(\w))*.rule2.((\w).rule1)*.(]) 

rule4 -> rule1 | rule3 
-1

NIEDORĘCZENIA zagnieżdżonych

\\s+(?![^\\[]*\\]) 

DLA zagnieżdżonych ([] wewnątrz [])

(?<!\\[[^\\]]*)\\s+(?![^\\[]*\\]) 
+0

+1 bardzo ładne rozwiązanie! – alfasin

+0

Kompilator skarży się, że w drugim wyrażeń regularnych występuje niepoprawna sekwencja specjalna. – arshajii

+0

To samo dotyczy pierwszego wyrażeń regularnych. – arshajii

4

Nie można tego zrobić z pojedynczym regex, po prostu dlatego, że nie może dopasowywać nawiasów otwartych/zamkniętych i obsługi klamr zagnieżdżonych.

Regeksy nie są kompletne, więc nawet jeśli może być wyglądać jak działa, będzie tak, że nie uda się.

Więc wolę zasugerować zaprogramowanie własnych kilku linii kodu, które z pewnością będą obsługiwać wszystkie przypadki.

Możesz utworzyć bardzo prostą gramatykę dla JavaCC lub AntLR lub użyć prostego parsera opartego na stosie.

+0

możesz to zrobić w regex .. i działa dobrze .. – Anirudha

+0

[[xx], [y]] z t [z [x] y] śmiało. – jdevelop

+0

zrobił to. 2 razy [tutaj] (http://stackoverflow.com/questions/12756651/split-a-tring-based-on-regex/12756722#12756722) i powyżej .. – Anirudha

3

Jak powiedziano w innych odpowiedziach, potrzebujesz do tego parsera. Oto ciąg, który nie działa z poprzednimi rozwiązaniami regex.

"[a b] c [a [d e] f g]" 

EDIT:

public static List<String> split(String s){ 
    List<String> l = new LinkedList<String>(); 
    int depth=0; 
    StringBuilder sb = new StringBuilder(); 
    for(int i=0; i<s.length(); i++){ 
     char c = s.charAt(i); 
     if(c=='['){ 
      depth++; 
     }else if(c==']'){ 
      depth--; 
     }else if(c==' ' && depth==0){ 
      l.add(sb.toString()); 
      sb = new StringBuilder(); 
      continue; 
     } 
     sb.append(c); 
    } 
    l.add(sb.toString()); 

    return l; 
} 
+0

możesz to zrobić w regex..u nie potrzebujesz parsera – Anirudha

+2

Jak możesz zarządzać wieloma zagnieżdżonymi [] z wyrażeniem regularnym? –

Powiązane problemy