Eu gosto da idéia do StringTokenizer porque é enumerável.
Mas também é obsoleto e substitui por String.split, que retorna um String [] chato (e não inclui os delimitadores).
Então, eu implementei um StringTokenizerEx que é um Iterable e que requer um verdadeiro regexp para dividir uma string.
Um regexp verdadeiro significa que não é uma 'Sequência de caracteres' repetida para formar o delimitador:
'o' corresponderá apenas a 'o' e dividirá 'ooo' em três delimitadores, com duas cadeias vazias dentro:
[o], '', [o], '', [o]
Mas o regexp o + retornará o resultado esperado ao dividir "aooob"
[], 'a', [ooo], 'b', []
Para usar este 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();
}
O código desta classe está disponível nos DZone Snippets .
Como de costume, para uma resposta de desafio de código (uma classe independente com casos de teste incluídos), copie e cole-a (em um diretório 'src / test') e execute-a . Seu método main () ilustra os diferentes usos.
Nota: (edição de final de 2009)
O artigo Considerações finais: Java Puzzler: Splitting Hairs faz um bom trabalho explicando o comportamento bizarro de String.split()
.
Josh Bloch até comentou em resposta a esse artigo:
Sim, isso é uma dor. FWIW, isso foi feito por uma boa razão: compatibilidade com Perl.
O cara que fez isso é Mike "madbot" McCloskey, que agora trabalha conosco no Google. Mike garantiu que as expressões regulares do Java passassem virtualmente em todos os testes de expressão regular do 30K Perl (e corriam mais rápido).
A biblioteca comum do Google Guava também contém um divisor que é:
- mais simples de usar
- mantido pelo Google (e não por você)
Portanto, pode valer a pena conferir. A partir da documentação inicial inicial (pdf) :
O JDK tem isso:
String[] pieces = "foo.bar".split("\\.");
É bom usar isso se você quiser exatamente o que ele faz: - expressão regular - resultado como uma matriz - sua maneira de lidar com peças vazias
Mini-quebra-cabeças: ", a ,, b,". Split (",") retorna ...
(a) "", "a", "", "b", ""
(b) null, "a", null, "b", null
(c) "a", null, "b"
(d) "a", "b"
(e) None of the above
Resposta: (e) Nenhuma das opções acima.
",a,,b,".split(",")
returns
"", "a", "", "b"
Apenas vazios finais são ignorados! (Quem sabe a solução alternativa para evitar o salto? É divertido ...)
De qualquer forma, nosso Splitter é simplesmente mais flexível: o comportamento padrão é simplista:
Splitter.on(',').split(" foo, ,bar, quux,")
--> [" foo", " ", "bar", " quux", ""]
Se você quiser recursos extras, peça-os!
Splitter.on(',')
.trimResults()
.omitEmptyStrings()
.split(" foo, ,bar, quux,")
--> ["foo", "bar", "quux"]
A ordem dos métodos de configuração não importa - durante a divisão, o corte ocorre antes de verificar se há vazios.