Mi piace l'idea di StringTokenizer perché è enumerabile.
Ma è anche obsoleto e sostituito da String.split che restituisce una stringa noiosa [] (e non include i delimitatori).
Quindi ho implementato un StringTokenizerEx che è un Iterable e che richiede una vera regexp per dividere una stringa.
Una vera regexp significa che non è una 'sequenza di caratteri' ripetuta per formare il delimitatore:
'o' corrisponderà solo a 'o' e dividere 'ooo' in tre delimitatori, con due stringhe vuote all'interno:
[o], '', [o], '', [o]
Ma il regexp o + restituirà il risultato atteso quando si divide "aooob"
[], 'a', [ooo], 'b', []
Per utilizzare questo 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();
}
Il codice di questa classe è disponibile su Snippet DZone .
Come al solito per una risposta a code challenge (una classe autonoma con casi di test inclusi), copiarla e incollarla (in una directory 'src / test') ed eseguirla . Il suo metodo main () illustra i diversi usi.
Nota: (modifica alla fine del 2009)
L'articolo Final Thoughts: Java Puzzler: Splitting Hairs fa un buon lavoro spiegando il comportamento bizzarro String.split().
Josh Bloch ha anche commentato in risposta a quell'articolo:
Sì, questo è un dolore. FWIW, è stato fatto per un'ottima ragione: compatibilità con Perl.
Il ragazzo che lo ha fatto è Mike "Madbot" McCloskey, che ora lavora con noi a Google. Mike si assicurò che le espressioni regolari di Java superassero praticamente tutti i test di espressione regolare Perl da 30K (e funzionassero più velocemente).
La libreria comune di Google Guava contiene anche uno Splitter che è:
- più semplice da usare
- gestito da Google (e non da te)
Quindi potrebbe valere la pena di essere verificato. Dalla loro documentazione iniziale approssimativa (pdf) :
JDK ha questo:
String[] pieces = "foo.bar".split("\\.");
Va bene usarlo se vuoi esattamente quello che fa: - espressione regolare - risultato come un array - il suo modo di gestire pezzi vuoti
Mini-puzzle: ", a ,, b,". Split (",") restituisce ...
(a) "", "a", "", "b", ""
(b) null, "a", null, "b", null
(c) "a", null, "b"
(d) "a", "b"
(e) None of the above
Risposta: (e) Nessuna delle precedenti.
",a,,b,".split(",")
returns
"", "a", "", "b"
Solo i vuoti finali vengono saltati! (Chi conosce la soluzione alternativa per evitare il salto? È divertente ...)
In ogni caso, il nostro Splitter è semplicemente più flessibile: il comportamento predefinito è semplicistico:
Splitter.on(',').split(" foo, ,bar, quux,")
--> [" foo", " ", "bar", " quux", ""]
Se vuoi funzionalità extra, chiedile!
Splitter.on(',')
.trimResults()
.omitEmptyStrings()
.split(" foo, ,bar, quux,")
--> ["foo", "bar", "quux"]
I metodi dell'ordine di configurazione non contano: durante la divisione, il taglio avviene prima di verificare la presenza di vuoti.