La suddivisione della stringa Java ha rimosso valori vuoti


286

Sto cercando di dividere il valore usando un separatore. Ma sto trovando risultati sorprendenti

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

Mi aspetto di ottenere 8 valori. [5,6,7, VUOTO, 8,9, VUOTO, VUOTO] Ma sto ottenendo solo 6 valori.

Qualsiasi idea e come risolvere. Indipendentemente dal valore EMPTY disponibile ovunque, dovrebbe essere nella matrice.

Risposte:


492

split(delimiter)per impostazione predefinita rimuove le stringhe vuote finali dall'array dei risultati. Per attivare questo meccanismo di tutto abbiamo bisogno di usare versione di overload di split(delimiter, limit)con limitset di valore negativo come

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

Qualche piccolo dettaglio in più:
split(regex)restituisce internamente il risultato split(regex, 0)e nella documentazione di questo metodo che puoi trovare

Il limitparametro controlla il numero di volte in cui viene applicato il modello e quindi influenza la lunghezza dell'array risultante.

Se il limite nè maggiore di zero, il modello verrà applicato al massimo n - 1 volte, la lunghezza dell'array non sarà maggiore di n e l'ultima voce dell'array conterrà tutti gli input oltre l'ultimo delimitatore corrispondente.

Se nonn è positivo, il modello verrà applicato il maggior numero di volte possibile e l'array può avere qualsiasi lunghezza.

Se nè zero, il modello verrà applicato il maggior numero di volte possibile, l'array può avere qualsiasi lunghezza e le stringhe vuote finali verranno scartate .

Eccezione :

Vale la pena ricordare che la rimozione di stringhe vuote finali ha senso solo se tali stringhe vuote vengono create dal meccanismo split . Quindi, "".split(anything)poiché non possiamo dividere ""ulteriormente, otterremo come [""]matrice di risultati .
Succede perché la divisione non è avvenuta qui, quindi ""nonostante sia vuota e il trailing rappresenta una stringa originale , non una stringa vuota creata dal processo di divisione.


2
Wow. ha funzionato alla grande. ma -1 come questo cambia tutto?
Reddy,

1
puoi persino provare condata.split("\\|", 8)
Subhrajyoti Majumder

23
Non usare split("\\|", 8)perché questo limita i primi otto token! Se la stringa è variabile, è necessario utilizzarla in split("\\|", -1)modo da creare un numero illimitato di token e non eliminare i token vuoti alla fine.
ADTC

2
@Reddy -1 ( o qualsiasi numero negativo in realtà, non importa quale sia il valore assoluto ) dice al metodo split di mantenere i token vuoti alla fine. Il valore predefinito è 0, che indica al metodo di eliminare i token vuoti alla fine dell'array.
ADTC

8
Apparentemente, molte persone si aspettavano che mantenere le stringhe vuote finali sia la funzionalità predefinita per split(regex). Sono finiti qui e hanno scoperto che non lo è.
Attila Tanyi,

32

Dalla documentazione di String.split(String regex):

Questo metodo funziona come se invocasse il metodo split a due argomenti con l'espressione data e un argomento limite pari a zero. Le stringhe vuote finali non sono pertanto incluse nell'array risultante.

Quindi dovrai usare la versione String.split(String regex, int limit)a due argomenti con un valore negativo:

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

Doc:

Se il limite n è maggiore di zero, il modello verrà applicato al massimo n - 1 volte, la lunghezza dell'array non sarà maggiore di n e l'ultima voce dell'array conterrà tutti gli input oltre l'ultimo delimitatore corrispondente. Se n non è positivo, il modello verrà applicato il maggior numero di volte possibile e l'array può avere qualsiasi lunghezza. Se n è zero, il modello verrà applicato il maggior numero di volte possibile, l'array può avere qualsiasi lunghezza e le stringhe vuote finali verranno scartate.

Questo non tralascerà alcun elemento vuoto, inclusi quelli finali.


4

Da String.split () Documento API :

Divide questa stringa attorno alle corrispondenze dell'espressione regolare fornita. Questo metodo funziona come se invocasse il metodo split a due argomenti con l'espressione data e un argomento limite pari a zero. Le stringhe vuote finali non sono pertanto incluse nell'array risultante.

String.split sovraccarico (regex, int) è più appropriato per il tuo caso.


1
Questo spiega il comportamento ma non risponde alla domanda.
Assylias,

@assylias l'ha aggiunto alla mia risposta ora :)
PermGenError il

4

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

Questo non è il vero requisito in ogni momento. Lo svantaggio di cui sopra è mostrato di seguito:

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

Quando mancano i dati:

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

Il requisito reale è che la lunghezza dovrebbe essere 7 anche se mancano dei dati. Perché ci sono casi come quando devo inserire nel database o qualcos'altro. Possiamo raggiungere questo obiettivo usando l'approccio seguente.

    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

Quello che ho fatto qui è, sto rimuovendo "|" pipe alla fine e quindi suddividere la stringa. Se hai "," come separatore, devi aggiungere ", $" all'interno di ReplaceAll.


1

potresti avere più separatori, inclusi spazi bianchi, virgole, punti e virgola, ecc. prendi quelli in gruppo ripetibile con [] +, come:

 String[] tokens = "a , b,  ,c; ;d,      ".split( "[,; \t\n\r]+" );

avrai 4 token: a, b, c, d

i separatori iniziali nella stringa di origine devono essere rimossi prima di applicare questa divisione.

come risposta alla domanda posta:

String data = "5|6|7||8|9||";
String[] split = data.split("[\\| \t\n\r]+");

spazi bianchi aggiunti per ogni evenienza se li avrai come separatori insieme a |

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.