Java String split eliminado valores vacíos


Estoy tratando de dividir el valor usando un separador. Pero estoy encontrando los resultados sorprendentes

String data = "5|6|7||8|9||";
String[] split = data.split("\\|");
System.out.println(split.length);

Estoy esperando obtener 8 valores. [5,6,7,VACÍO, 8, 9, VACÍO, VACÍO] Pero estoy obteniendo solo 6 valores.

Cualquier idea y cómo arreglar. No importa el valor VACÍO viene en cualquier lugar, debe estar en matriz.

Author: Reddy, 2013-01-30

5 answers

split(delimiter) de forma predeterminada elimina las cadenas vacías finales de la matriz de resultados. Para desactivar este mecanismo necesitamos usar la versión sobrecargada de split(delimiter, limit) con limit establecido en valor negativo como

String[] split = data.split("\\|", -1);

Poco más detalles:
split(regex) internamente devuelve el resultado de split(regex, 0) y en documentación de este método se puede encontrar (énfasis mío)

El parámetro limit controla el número de veces que se aplica el patrón y, por lo tanto, afecta a la longitud del array resultante.

Si el límite n es mayor que cero entonces el patrón se aplicará como máximo n - 1 veces, la longitud del array no será mayor que n, y la última entrada del array contendrá toda la entrada más allá del último delimitador coincidente.

Si n es no positivo entonces el patrón se aplicará tantas veces como sea posible y la matriz puede tener cualquier longitud.

Si n es cero entonces el patrón se aplicará tantas veces como sea posible, el array puede tener cualquier longitud, y las cadenas vacías finales serán descartadas.

Excepción :

Vale la pena mencionar que la eliminación de cadenas vacías al final tiene sentido solo si dichas cadenas vacías se crean mediante el mecanismo de división. Así que para "".split(anything) ya que no podemos dividir "" más lejos obtendremos como resultado [""] matriz.
Sucede porque split no sucedió aquí, por lo que "" a pesar de estar vacío y al final representa cadena original , no cadena vacía que se creó mediante el proceso de división.

 362
Author: jlordo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-21 12:03:43

De la documentación de String.split(String regex):

Este método funciona como si invocara el método split de dos argumentos con la expresión dada y un argumento límite de cero. Por lo tanto, las cadenas vacías finales no se incluyen en el array resultante.

Así que tendrá que usar la versión de dos argumentosString.split(String regex, int limit) con un valor negativo:

String[] split = data.split("\\|",-1);

Doc:

Si el límite n es mayor que cero, entonces el patrón se aplicará en la mayoría de n - 1 veces, la longitud de la matriz no será mayor que n, y la última entrada de la matriz contendrá toda la entrada más allá del último delimitador coincidente. Si n no es positivo, entonces el patrón se aplicará tantas veces como sea posible y la matriz puede tener cualquier longitud. Si n es cero, entonces el patrón se aplicará tantas veces como sea posible, la matriz puede tener cualquier longitud, y las cadenas vacías finales se descartarán.

Esto no dejará fuera ningún elemento vacío, incluyendo los que siguen.

 31
Author: ppeterka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-30 10:54:03

Desde Cuerda.doc de API de split ():

Divide esta cadena alrededor de las coincidencias de la expresión regular dada. Este método funciona como si invocara el método split de dos argumentos con la expresión dada y un argumento límite de cero. Trailing vacío por lo tanto, las cadenas no se incluyen en el array resultante.

Sobrecargado Cuerda.split(regex, int) es más apropiado para su caso.

 4
Author: PermGenError,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-30 10:44:36

Otra opción es usar el divisor de Guayaba. No tiene la sobrecarga de una expresión regular (que no necesita en este caso) y por defecto no descarta cadenas finales vacías.

Por ejemplo:

 String data = "5|6|7||8|9||";
 Iterable<String> results = Splitter.on('|').split(data);
 // convert to array
 String[] asArray = Iterables.toArray(results, String.class);

Para más información, ver wiki: https://github.com/google/guava/wiki/StringsExplained

 3
Author: nickool,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-28 23:46:26

String[] split = data.split("\\|",-1);

Este no es el requisito real en todo el tiempo. El inconveniente de lo anterior se muestra a continuación:

Scenerio 1:
When all data are present:
    String data = "5|6|7||8|9|10|";
    String[] split = data.split("\\|");
    String[] splt = data.split("\\|",-1);
    System.out.println(split.length); //output: 7
    System.out.println(splt.length); //output: 8

Cuando faltan datos:

Scenerio 2: Data Missing
    String data = "5|6|7||8|||";
    String[] split = data.split("\\|");
    String[] splt = data.split("\\|",-1);
    System.out.println(split.length); //output: 5
    System.out.println(splt.length); //output: 8

El requisito real es que la longitud debe ser 7, aunque faltan datos. Porque hay casos como cuando necesito insertar en la base de datos o algo más. Podemos lograr esto utilizando el siguiente enfoque.

    String data = "5|6|7||8|||";
    String[] split = data.split("\\|");
    String[] splt = data.replaceAll("\\|$","").split("\\|",-1);
    System.out.println(split.length); //output: 5
    System.out.println(splt.length); //output:7

Lo que he hecho aquí es, estoy eliminando la tubería "|" al final y luego dividiendo la cadena. Si usted tiene "," como un separador entonces usted necesita agregar", repl " dentro de replaceAll.

 0
Author: Yanish Pradhananga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-09 05:48:24