2013-05-25 17 views
8

Sto elaborando una determinata riga letta da un file .csv utilizzando String.split(",") e rilevando che la stringa vuota finale dopo che l'ultimo delimitatore non lo ha inserito nell'array creato dalla funzione split.Quando si elabora una stringa csv con un campo finale vuoto, myString.split (",") restituisce un numero errato di voci di array

Ecco i valori delle variabili che causano l'errore:

String toSplit = "1,Some Value,31337,Another Value,"; 
String[] values = toSplit.split(","); 

L'array values finisce con meno di conteggio atteso di elementi dell'array. La matrice è creato:

values[0] : '1' 
values[1] : 'Some Value' 
values[2] : '31337' 
values[3] : 'Another Value' 

con un values[4] un'eccezione ArrayIndexOutOfBounds.

La matrice che voglio è:

values[0] : '1' 
values[1] : 'Some Value' 
values[2] : '31337' 
values[3] : 'Another Value' 
values[4] : '' 

Un avvertimento: Sto leggendo l'output di un altro file .csv creatore e non voglio usare delimitatori di stringa o di lanciare un '' carattere di spazio bianco in luoghi dove i dati sono vuoti. (es .: non voglio: toSplit = "1,Some Value,31337,Another Value, " con spazi bianchi alla fine.)

Si tratta di un bug in String.split() e c'è una soluzione alternativa/un'altra?

risposta

13

Capito come stavo inserendo la domanda! Utilizzare stringObj.split (",", numDelimitersExpected) o, come sottolineato da @Supericy, stringObj.split (",", -1).

Secondo la documentazione Android circa stringObj.split(delimiter) una chiamata a line.split(",") è equivalente a una chiamata a line.split(",", 0) con il secondo argomento riferendosi limit, che imposta il 'numero massimo di voci' e definisce il 'trattamento di trascinamento vuoto stringhe '. Guardando la documentazione per stringObj.split(delimiter) si afferma che con 'le stringhe vuote non verranno restituite'.

La soluzione è quella di utilizzare una chiamata a split(",", limit) con limit insieme al numero di voci matrice che ci si aspetta di tornare. Nel mio caso un limite impostato su 5 restituisce l'array

values[0] : '1' 
values[1] : 'Some Value' 
values[2] : '31337' 
values[3] : 'Another Value' 
values[4] : '' 

che è esattamente quello che volevo. Problema risolto.

Infatti, anche se la stringa toSplit ha meno delimitatori di limit, una chiamata con un set limit creerà ancora elementi dell'array vuoto fino a limit. Ad esempio, con la stessa stringa di input come nella mia domanda:

String toSplit = "1,Some Value,31337,Another Value," 

una chiamata String values[] = toSplit.split(",", 8) restituisce la matrice

values[0] : '1' 
values[1] : 'Some Value' 
values[2] : '31337' 
values[3] : 'Another Value' 
values[4] : '' 
values[5] : '' 
values[6] : '' 
values[7] : '' 

Neat!

Nota: Java String.split(delimiter) di Oracle ha la stessa funzionalità con i documenti Android vincenti per la loro spiegazione più concisa. (:

Edit: Come ha aggiunto @Supericy, toSplit.split(",", -1) sarebbe anche tornare correttamente il trailing voce vuota Grazie per l'aggiunta

+0

Entro un minuto la domanda e la risposta sono presenti:.!! D – Lion

+2

In alternativa, è può usare 'String.split (delimiter, -1)' se non si conosce il numero di voci prima del tempo. Inoltre, javadoc * * ti dice che sta chiamando 'String.split (del, limit)' con un limite di zero, quindi la tua ragione dietro l'androide dei documenti è migliore. – Supericy

+0

@Supericy: buona chiamata con limite -1! E sì, ho letto che i documenti Oracle spiegano anche quella funzionalità, ma i documenti Android fanno uso di incapsulamento funzionale che dice esattamente la stessa cosa cosa come i documenti Oracle, ma in modo più conciso. Nota: non ho dichiarato che la documentazione fosse sbagliata, solo che era meno concisa. Sono entrambi completi. Uno è completo e anche più corto, quindi vince. (: Grazie per il tuo contributo! – reor