Java String split menghapus nilai-nilai kosong


286

Saya mencoba untuk membagi Nilai menggunakan pemisah. Tetapi saya menemukan hasil yang mengejutkan

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

Saya berharap mendapatkan 8 nilai. [5,6,7, KOSONG, 8,9, KOSONG, KOSONG] Tapi saya hanya mendapatkan 6 nilai.

Ada ide dan cara memperbaikinya. Tidak peduli nilai KOSONG datang di mana pun, itu harus dalam array.

Jawaban:


492

split(delimiter)secara default menghapus jejak kosong dari array hasil. Untuk mematikan mekanisme ini, kita perlu menggunakan versi overload split(delimiter, limit)dengan limitset ke nilai negatif seperti

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

Sedikit lebih detail: secara
split(regex)internal mengembalikan hasil split(regex, 0)dan dalam dokumentasi metode ini Anda dapat menemukan (penekanan milik saya)

The limitparameter mengontrol jumlah kali pola yang diterapkan dan karena itu mempengaruhi panjang array yang dihasilkan.

Jika batas nini lebih besar dari nol maka pola tersebut akan diterapkan paling n - 1 kali, panjang array akan menjadi tidak lebih besar dari n, dan entri terakhir array akan berisi semua masukan luar pembatas cocok terakhir.

Jika nadalah non-positif maka pola tersebut akan diterapkan sebanyak mungkin dan array dapat memiliki panjang apapun.

Jika nyaitu nol maka pola tersebut akan diterapkan sebanyak mungkin, array dapat memiliki setiap panjang, dan mengikuti string kosong akan dibuang .

Pengecualian :

Perlu disebutkan bahwa menghilangkan string kosong yang masuk akal hanya jika string kosong seperti itu dibuat oleh mekanisme split . Jadi "".split(anything)karena kita tidak dapat memisahkan ""lebih jauh kita akan mendapatkan sebagai [""]array hasil .
Itu terjadi karena perpecahan tidak terjadi di sini, jadi ""meskipun kosong dan tertinggal mewakili string asli , bukan string kosong yang dibuat oleh proses pemisahan.


2
Wow. yang bekerja dengan sangat baik. tapi -1 bagaimana ini mengubah segalanya?
Reddy

1
Anda bahkan dapat mencoba dengandata.split("\\|", 8)
Subhrajyoti Majumder

23
Jangan gunakan split("\\|", 8)karena ini membatasi ke delapan token pertama! Jika string Anda variabel, Anda harus menggunakannya split("\\|", -1)sehingga membuat token yang tidak terbatas dan tidak membuang token kosong di akhir.
ADTC

2
@Reddy -1 ( atau angka negatif sebenarnya, tidak peduli apa nilai absolutnya ) memberitahu metode split untuk menjaga token kosong di akhir. Standarnya adalah 0, yang memberi tahu metode untuk membuang token kosong di akhir array.
ADTC

8
Rupanya, banyak orang berharap bahwa menjaga string kosong tertinggal adalah fungsi standar untuk split(regex). Mereka berakhir di sini dan ternyata ternyata tidak.
Attila Tanyi

32

Dari dokumentasi String.split(String regex):

Metode ini berfungsi seolah-olah dengan memanggil metode split dua argumen dengan ekspresi yang diberikan dan argumen batas nol. Trailing string kosong karenanya tidak termasuk dalam array yang dihasilkan.

Jadi, Anda harus menggunakan dua versi argumen String.split(String regex, int limit)dengan nilai negatif:

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

Dokter:

Jika batas n lebih besar dari nol maka pola akan diterapkan paling banyak n - 1 kali, panjang array tidak akan lebih besar dari n, dan entri terakhir array akan berisi semua input di luar pembatas yang cocok terakhir. Jika n adalah non-positif maka pola akan diterapkan sebanyak mungkin dan array dapat memiliki panjang apa pun. Jika n adalah nol maka polanya akan diterapkan sebanyak mungkin, array dapat memiliki panjang berapa pun, dan trailing string kosong akan dibuang.

Ini tidak akan meninggalkan elemen kosong, termasuk yang tertinggal.


4

Dari String.split () API Doc :

Pisahkan string ini di sekitar kecocokan dari ekspresi reguler yang diberikan. Metode ini berfungsi seolah-olah dengan memanggil metode split dua argumen dengan ekspresi yang diberikan dan argumen batas nol. Trailing string kosong karenanya tidak termasuk dalam array yang dihasilkan.

String.split (Regex, int) yang kelebihan beban lebih cocok untuk kasus Anda.


1
Itu menjelaskan perilaku tetapi tidak menjawab pertanyaan.
assylias

@assylias menambahkannya ke jawaban saya sekarang :)
PermGenError

4

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

Ini bukan persyaratan aktual sepanjang waktu. Kekurangan di atas ditunjukkan di bawah ini:

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

Ketika data hilang:

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

Persyaratan sebenarnya adalah panjang harus 7 meskipun ada data yang hilang. Karena ada kasus-kasus seperti ketika saya perlu memasukkan dalam database atau sesuatu yang lain. Kita dapat mencapai ini dengan menggunakan pendekatan di bawah ini.

    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

Apa yang saya lakukan di sini adalah, saya menghapus "|" pipa di ujung lalu pisahkan String. Jika Anda memiliki "," sebagai pemisah maka Anda perlu menambahkan ", $" di dalam replaceAll.


1

Anda mungkin memiliki beberapa pemisah, termasuk karakter spasi putih, koma, titik koma, dll. ambil yang dalam grup berulang dengan [] +, seperti:

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

Anda akan memiliki 4 token - a, b, c, d

pemisah utama dalam string sumber perlu dihapus sebelum menerapkan pemisahan ini.

sebagai jawaban atas pertanyaan yang diajukan:

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

spasi putih ditambahkan untuk berjaga-jaga jika Anda akan memiliki mereka sebagai pemisah bersama |

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.