2010-04-28 10 views
5

Potrzebuję móc podzielić wejściowy ciąg przecinkami, średnikami lub białymi znakami (lub mieszanką trzech). Chciałbym również traktować wiele kolejnych ograniczników w danych wejściowych jako pojedynczy separator. Oto co mam do tej pory:String.split() - pasujące wiodące puste ciąg przed pierwszym ogranicznikiem?

String regex = "[,;\\s]+";  
return input.split(regex); 

To działa, z wyjątkiem, gdy ciąg wejściowy zaczyna się od jednego z separatorów, przy czym pierwszy element tablicy wyników jest pusty. Nie chcę, aby mój wynik zawierał puste ciągi znaków, więc coś w stylu ",,,, ZERO ;,; ONE, DRUGIE ;," zwraca tylko tablicę z trzema elementami zawierającą napisy wielkimi literami.

Czy istnieje lepszy sposób, aby to zrobić, niż zdejmowanie wiodących znaków pasujących do mojego reg-ex przed wywołaniem String.split?

Z góry dziękuję!

+0

Nie publikuję jako odpowiedzi, ponieważ nie pamiętam interfejsu API regex Java, ale można po prostu wyszukiwać ciągi znaków bez ograniczników zamiast podziału na ograniczniki, np. używając wyrażeń regularnych takich jak '[^,; \ s] +'. –

+0

Podobno identyczne pytanie, nowsze, ale z lepiej zaakceptowaną odpowiedzią: https://stackoverflow.com/questions/9389503/how-to-prevent-java-lang-string-split-from-creating-a-leading-empty-string –

Odpowiedz

3

Jeśli przez "lepiej" masz na myśli wyższą wydajność, możesz spróbować utworzyć wyrażenie regularne, które pasuje do tego, co chcesz dopasować i użyć w pętli Matcher.find i wyciągnąć dopasowania, gdy je znajdziesz. W pierwszej kolejności zapisuje się ciąg znaków. Ale zmierz, dla siebie, aby zobaczyć, który jest szybszy dla twoich danych.

Jeśli przez "lepsze" masz na myśli prostsze, to nie, nie sądzę, że jest prostszy sposób niż sugerowałeś: usunięcie wiodących separatorów przed zastosowaniem podziału.

6

Nie, nie ma. Można zignorować spływu tylko ograniczniki dostarczając 0 jako drugi parametr do rozłamu STRING() metoda:

return input.split(regex, 0); 

ale dla wiodących ograniczniki, trzeba będzie rozebrać je najpierw:

return input.replaceFirst("^"+regex, "").split(regex, 0); 
+0

Negatywny parametr? 'Jeśli n jest równe zero, wzorzec zostanie zastosowany tyle razy, ile to możliwe, tablica może mieć dowolną długość, a końcowe ciągi puste będą odrzucane." Od http://java.sun.com/javase/6/docs/ api/java/lang/String.html # split% 28java.lang.String,% 20int% 29 –

+0

Whoops, tak, miałem na myśli 0. Dzięki! –

+0

+1 za naprawienie :) –

1

Można też potencjalnie wykorzystać StringTokenizer zbudować listę, w zależności co trzeba z nim zrobić:

StringTokenizer st = new StringTokenizer(",,,ZERO;,ONE TWO", ",; ", false); 
while(st.hasMoreTokens()) { 
    String str = st.nextToken(); 
    //add to list, process, etc... 
} 

Jako zastrzeżeniem jednak, trzeba zdefiniować każdy potencjalny Znaki Niedrukowalne oddzielnie w drugi argument do konstruktora.

2

Prawie wszystkie obiekty podziału w JDK są zepsute w taki czy inny sposób. Byłbyś lepiej wyłączyć za pomocą klasy innych firm, takich jak Splitter, który jest zarówno elastyczny i poprawne w jaki sposób radzi sobie puste znaki i spacje:

Splitter.on(CharMatcher.anyOf(";,").or(CharMatcher.WHITESPACE)) 
    .omitEmptyStrings() 
    .split(",,,ZERO;,ONE TWO"); 

będzie uzyskując Iterable < String> zawierający „zero”, "ONE", "TWO"

Powiązane problemy