Podoba mi się pomysł StringTokenizer, ponieważ jest on wyliczalny.
Ale jest również przestarzały i zastąpiony przez String.split, które zwracają nudny String [] (i nie zawiera ograniczników).
Zaimplementowałem więc StringTokenizerEx, który jest iterowalny i który wymaga prawdziwego wyrażenia regularnego do podzielenia łańcucha.
Prawdziwe wyrażenie regularne oznacza, że nie jest to „sekwencja znaków” powtarzana w celu utworzenia separatora:
„o” będzie pasować tylko do „o” i podzieli „ooo” na trzy separatory z dwoma pustymi ciągami wewnątrz:
[o], '', [o], '', [o]
Ale wyrażenie regularne o + zwróci oczekiwany wynik po podzieleniu „aooob”
[], 'a', [ooo], 'b', []
Aby użyć tego StringTokenizerEx:
final StringTokenizerEx aStringTokenizerEx = new StringTokenizerEx("boo:and:foo", "o+");
final String firstDelimiter = aStringTokenizerEx.getDelimiter();
for(String aString: aStringTokenizerEx )
{
// uses the split String detected and memorized in 'aString'
final nextDelimiter = aStringTokenizerEx.getDelimiter();
}
Kod tej klasy jest dostępny na stronie DZone Snippets .
Jak zwykle w przypadku odpowiedzi na wyzwanie kodu (jedna samodzielna klasa z dołączonymi przypadkami testowymi), skopiuj ją i wklej (w katalogu 'src / test') i uruchom . Jego metoda main () ilustruje różne zastosowania.
Uwaga: (edycja z końca 2009 r.)
Artykuł Final Thoughts: Java Puzzler: Splitting Hairs dobrze się spisuje wyjaśniając dziwne zachowanie String.split().
Josh Bloch skomentował nawet w odpowiedzi na ten artykuł:
Tak, to jest ból. FWIW, zrobiono to z bardzo dobrego powodu: kompatybilności z Perlem.
Facet, który to zrobił, to Mike „madbot” McCloskey, który teraz współpracuje z nami w Google. Mike upewnił się, że wyrażenia regularne Javy przeszły praktycznie każdy z testów wyrażeń regularnych 30 K Perl (i działały szybciej).
Guava z wspólnej biblioteki Google zawiera również Splitter, który jest:
- prostszy w użyciu
- utrzymywany przez Google (a nie przez ciebie)
Więc może warto to sprawdzić. Z ich wstępnej wstępnej dokumentacji (pdf) :
JDK ma to:
String[] pieces = "foo.bar".split("\\.");
Można to wykorzystać, jeśli chcesz dokładnie to, co robi: - wyrażenie regularne - wynik jako tablica - sposób obsługi pustych elementów
Mini-puzzler: „, a ,, b”. Split („,”) zwraca ...
(a) "", "a", "", "b", ""
(b) null, "a", null, "b", null
(c) "a", null, "b"
(d) "a", "b"
(e) None of the above
Odpowiedź: (e) Żadne z powyższych.
",a,,b,".split(",")
returns
"", "a", "", "b"
Pomijane są tylko puste opróżnienia! (Kto zna obejście, aby zapobiec pomijaniu? To zabawne ...)
W każdym razie nasz Splitter jest po prostu bardziej elastyczny: Domyślne zachowanie jest uproszczone:
Splitter.on(',').split(" foo, ,bar, quux,")
--> [" foo", " ", "bar", " quux", ""]
Jeśli chcesz dodatkowych funkcji, poproś o nie!
Splitter.on(',')
.trimResults()
.omitEmptyStrings()
.split(" foo, ,bar, quux,")
--> ["foo", "bar", "quux"]
Kolejność metod konfiguracji nie ma znaczenia - podczas podziału przycinanie odbywa się przed sprawdzeniem pustych miejsc.