Além disso, parece inconsistente com o comportamento observado quando a string contém apenas uma instância do separador. Neste caso, o resultado é efetivamente um array vazio: ",". Split (","). Length == 0
LD.
Respostas:
37
Pela mesma razão que
",test" split ','
e
",test," split ','
retornará uma matriz de tamanho 2. Tudo antes da primeira correspondência é retornado como o primeiro elemento.
Mas a laranja não está vazia (idk se é isso que oluies significava), é uma laranja. Talvez dividir uma laranja que deveria estar lá, mas não está, então você recebe de volta um único valor: um espaço vazio xD
Nick Rolando
8
Esta é uma conversa profunda.
31
Essa metáfora faz sentido "orange".split(','), mas não é obviamente relevante para dividir strings vazias. Se eu dividir minha falta de laranja zero vezes, ainda não tenho laranja; representamos isso como uma lista vazia de sem laranja, uma lista de exatamente uma sem laranja, uma lista de doze sem laranja, ou o quê? Não é uma questão de com o que acabamos, mas como o representamos.
Matchu
1
Mas se você dividir um livro inexistente pelas páginas, não obterá nada.
SMUsamaShah
49
Os métodos de divisão Java e Scala operam em duas etapas como esta:
Primeiro, divida a string por delimitador. A consequência natural é que, se a string não contém o delimitador, um array de singleton contendo apenas a string de entrada é retornado,
Em segundo lugar, remova todas as strings vazias mais à direita. Este é o motivo pelo qual ",,,".split(",")retorna um array vazio.
De acordo com isso, o resultado de "".split(",")deve ser um array vazio por causa da segunda etapa, certo?
Deveria. Infelizmente, este é um caso de canto introduzido artificialmente. E isso é ruim, mas pelo menos ele está documentado em java.util.regex.Pattern, se você se lembrar de tomar uma olhada na documentação:
Para n == 0, o resultado é igual a n <0, exceto que as strings vazias finais não serão retornadas. (Observe que o caso em que a própria entrada é uma string vazia é especial, conforme descrito acima, e o parâmetro limit não se aplica lá.)
Solução 1: sempre passe -1 como o segundo parâmetro
Portanto, aconselho você a sempre passar n == -1como o segundo parâmetro (isso pulará a etapa dois acima), a menos que você saiba especificamente o que deseja alcançar / tenha certeza de que a string vazia não é algo que seu programa obteria como entrada.
Solução 2: usar a classe Guava Splitter
Se você já está usando Guava em seu projeto, você pode tentar a classe Divisor (documentação) . Tem uma API muito rica e torna o seu código muito fácil de entender.
+1, esta é a única resposta que realmente cita a documentação e aponta que ela é inconsistente. No entanto, não encontrei a parte destacada do comentário em meu JavaDoc.
Yogu
Encontrei-o em java.util.regex.Pattern, mas parece que quase não existe mais. No momento da escrita, ele definitivamente estava presente na árvore de código-fonte oficial do OpenJDK como um javadoc. android.googlesource.com/platform/libcore/+/… Talvez devêssemos relatar um bug?
Rok Kralj
Seria uma boa ideia relatar um bug - o comportamento definitivamente não será alterado, mas deve pelo menos ser documentado.
Yogu
@RokKralj Android não usava a biblioteca OpenJDK, mas era baseado no Apache Harmony, então talvez você esteja procurando no lugar errado?
lxgr
1
"".split (",", n)gera uma matriz de um elemento para n em (-1, 0, 1) com Oracle JDK 8. Seria bom obter uma lista de tokens não vazios apenas - acho que um regex completo pode ser necessário (algo como "[^,\\s]+[^,]*[^,\\s]*").
simon.watts
40
A divisão de uma string vazia retorna a string vazia como o primeiro elemento. Se nenhum delimitador for encontrado na string de destino, você obterá uma matriz de tamanho 1 que contém a string original, mesmo se estiver vazia.
Errado. A divisão remove todas as strings vazias mais à direita, portanto, o resultado deve ser um array vazio. Veja minha resposta. ",".split(",")retorna uma matriz vazia.
Errado. A divisão remove todas as strings vazias mais à direita, portanto, o resultado deve ser um array vazio. Veja minha resposta. ",".split(",")retorna uma matriz vazia.
Rok Kralj de
5
Em todas as linguagens de programação, sei que uma string em branco ainda é uma String válida. Portanto, fazer uma divisão usando qualquer delimitador sempre retornará uma única matriz de elemento em que esse elemento é a String em branco. Se fosse uma string nula (não em branco), o problema seria diferente.
Acho que é uma função de biblioteca e não uma parte da linguagem. Por exemplo, no google goiaba você pode omitir strings vazias. > Iterable <String> pieces = com.google.common.base.Splitter.on (','). OmitEmptyStrings (). Split ("");
oluies
2
Este splitcomportamento é herdado do Java, para melhor ou para pior ...
Scala não sobrescreve a definição do Stringprimitivo.
O parâmetro limit controla o número de vezes que o padrão é aplicado e, portanto, afeta o comprimento da matriz resultante. Se o limite n for maior que zero, o padrão será aplicado no máximo n - 1 vezes, o comprimento da matriz não será maior do que n e a última entrada da matriz conterá todas as entradas além do último delimitador correspondente. Se n for não positivo, o padrão será aplicado tantas vezes quanto possível e a matriz pode ter qualquer comprimento. Se n for zero, o padrão será aplicado tantas vezes quanto possível, a matriz pode ter qualquer comprimento e as cadeias de caracteres vazias posteriores serão descartadas.
ou seja, você pode definir o limit=-1para obter o comportamento de (todos?) outros idiomas:
Parece ser bem conhecido que o comportamento do Java é bastante confuso, mas:
O comportamento acima pode ser observado de pelo menos Java 5 a Java 8.
Houve uma tentativa de alterar o comportamento para retornar um array vazio ao dividir uma string vazia em JDK-6559590 . No entanto, logo foi revertido em JDK-8028321 quando causa regressão em vários lugares. A mudança nunca chega ao lançamento inicial do Java 8.
Nota: O método de divisão não estava em Java desde o início (não está em 1.0.2 ), mas na verdade existe a partir de pelo menos 1.4 (por exemplo, consulte JSR51 por volta de 2002). Ainda estou investigando ...
O que não está claro é por que Java escolheu isso em primeiro lugar (minha suspeita é que era originalmente um descuido / bug em um "caso extremo"), mas agora irrevogavelmente embutido na linguagem e assim permanece .
Não tenho certeza se isso responde à pergunta - embora possa ser verdade para o exemplo dado aqui, não ajuda com o caso da string vazia - "".split(",")ainda retorna uma única matriz de elemento como [""].
DaveyDaveDave
@DaveyDaveDave é o comportamento esperado de qualquer outra linguagem. O ",,,," é o comportamento bizarro / diferente no Scala, e diferente do caso "".
Andy Hayden,
0
A string vazia não tem nenhum status especial ao dividir uma string. Você pode usar:
Respostas:
Pela mesma razão que
e
retornará uma matriz de tamanho 2. Tudo antes da primeira correspondência é retornado como o primeiro elemento.
fonte
"".split("wtf").length
retorna 0. Somente em JS é 1.: /"," split ","
retorna um array de 0?Se você dividir uma laranja zero vezes, terá exatamente um pedaço - a laranja.
fonte
"orange".split(',')
, mas não é obviamente relevante para dividir strings vazias. Se eu dividir minha falta de laranja zero vezes, ainda não tenho laranja; representamos isso como uma lista vazia de sem laranja, uma lista de exatamente uma sem laranja, uma lista de doze sem laranja, ou o quê? Não é uma questão de com o que acabamos, mas como o representamos.Os métodos de divisão Java e Scala operam em duas etapas como esta:
",,,".split(",")
retorna um array vazio.De acordo com isso, o resultado de
"".split(",")
deve ser um array vazio por causa da segunda etapa, certo?Deveria. Infelizmente, este é um caso de canto introduzido artificialmente. E isso é ruim, mas pelo menos ele está documentado em
java.util.regex.Pattern
, se você se lembrar de tomar uma olhada na documentação:Solução 1: sempre passe -1 como o segundo parâmetro
Portanto, aconselho você a sempre passar
n == -1
como o segundo parâmetro (isso pulará a etapa dois acima), a menos que você saiba especificamente o que deseja alcançar / tenha certeza de que a string vazia não é algo que seu programa obteria como entrada.Solução 2: usar a classe Guava Splitter
Se você já está usando Guava em seu projeto, você pode tentar a classe Divisor (documentação) . Tem uma API muito rica e torna o seu código muito fácil de entender.
fonte
"".split (",", n)
gera uma matriz de um elemento para n em (-1, 0, 1) com Oracle JDK 8. Seria bom obter uma lista de tokens não vazios apenas - acho que um regex completo pode ser necessário (algo como"[^,\\s]+[^,]*[^,\\s]*"
).A divisão de uma string vazia retorna a string vazia como o primeiro elemento. Se nenhum delimitador for encontrado na string de destino, você obterá uma matriz de tamanho 1 que contém a string original, mesmo se estiver vazia.
fonte
",".split(",")
retorna uma matriz vazia."a".split(",")
->"a"
portanto"".split(",")
->""
fonte
",".split(",")
retorna uma matriz vazia.Em todas as linguagens de programação, sei que uma string em branco ainda é uma String válida. Portanto, fazer uma divisão usando qualquer delimitador sempre retornará uma única matriz de elemento em que esse elemento é a String em branco. Se fosse uma string nula (não em branco), o problema seria diferente.
fonte
Este
split
comportamento é herdado do Java, para melhor ou para pior ...Scala não sobrescreve a definição do
String
primitivo.Observe que você pode usar o
limit
argumento para modificar o comportamento :ou seja, você pode definir o
limit=-1
para obter o comportamento de (todos?) outros idiomas:Parece ser bem conhecido que o comportamento do Java é bastante confuso, mas:
Nota: O método de divisão não estava em Java desde o início (não está em 1.0.2 ), mas na verdade existe a partir de pelo menos 1.4 (por exemplo, consulte JSR51 por volta de 2002). Ainda estou investigando ...
O que não está claro é por que Java escolheu isso em primeiro lugar (minha suspeita é que era originalmente um descuido / bug em um "caso extremo"), mas agora irrevogavelmente embutido na linguagem e assim permanece .
fonte
"".split(",")
ainda retorna uma única matriz de elemento como[""]
.A string vazia não tem nenhum status especial ao dividir uma string. Você pode usar:
fonte