Selain itu, tampaknya tidak konsisten dengan perilaku yang diamati saat string hanya berisi satu contoh pemisah. Dalam hal ini hasilnya adalah array kosong: ",". Split (","). Length == 0
LD.
Jawaban:
37
Untuk alasan yang sama itu
",test" split ','
dan
",test," split ','
akan mengembalikan larik berukuran 2. Segala sesuatu sebelum pertandingan pertama dikembalikan sebagai elemen pertama.
Tapi jeruknya tidak kosong (idk kalau itu yang dimaksud oluies), itu jeruk. Mungkin membelah jeruk yang seharusnya ada, tetapi sebenarnya tidak, jadi Anda mendapatkan kembali satu nilai: ruang kosong xD
Nick Rolando
8
Ini adalah percakapan yang mendalam.
31
Metafora ini masuk akal "orange".split(','), tetapi tidak jelas relevan untuk memisahkan string kosong. Jika saya membagi kekurangan jeruk saya nol kali, saya masih tidak memiliki jeruk; apakah kita menyatakan itu sebagai daftar kosong tanpa jeruk, daftar persis satu tidak ada jeruk, daftar dua belas tidak ada jeruk, atau apa? Ini bukan pertanyaan tentang apa yang akan kita dapatkan, tapi bagaimana kita mewakilinya.
Matchu
1
Tetapi jika Anda memisahkan buku yang tidak ada dengan halaman-halamannya, Anda tidak akan mendapatkan apa-apa.
SMUsamaShah
49
Metode pemisahan Java dan Scala beroperasi dalam dua langkah seperti ini:
Pertama, pisahkan string dengan pembatas. Konsekuensi alami adalah jika string tidak berisi pemisah, array tunggal yang hanya berisi string input dikembalikan,
Kedua, hapus semua string kosong paling kanan. Inilah alasannya ",,,".split(",")mengembalikan array kosong.
Menurut ini, hasil dari "".split(",")harus berupa larik kosong karena langkah kedua, bukan?
Itu harus. Sayangnya, ini adalah casing sudut yang diperkenalkan secara artifisial. Dan yang buruk, tapi setidaknya itu didokumentasikan dalam java.util.regex.Pattern, jika Anda ingat untuk melihat dokumentasi:
Untuk n == 0, hasilnya adalah untuk n <0, kecuali string kosong tidak akan dikembalikan. (Perhatikan bahwa kasus di mana masukan itu sendiri adalah string kosong yang khusus, seperti dijelaskan di atas, dan parameter batas tidak berlaku di sana.)
Solusi 1: Selalu berikan -1 sebagai parameter kedua
Jadi, saya menyarankan Anda untuk selalu lulus n == -1sebagai parameter kedua (ini akan melewatkan langkah kedua di atas), kecuali Anda secara khusus tahu apa yang ingin Anda capai / Anda yakin bahwa string kosong bukanlah sesuatu yang akan didapat program Anda sebagai input.
Solusi 2: Gunakan kelas Guava Splitter
Jika Anda sudah menggunakan Guava dalam proyek Anda, Anda dapat mencoba kelas Splitter (dokumentasi) . Ini memiliki API yang sangat kaya, dan membuat kode Anda sangat mudah dipahami.
+1, ini adalah satu-satunya jawaban yang benar-benar mengutip dokumentasi dan menunjukkan bahwa itu tidak konsisten. Namun, saya tidak menemukan bagian yang disorot dari komentar tersebut di JavaDoc saya.
Yogu
Saya telah menemukannya di java.util.regex.Pattern, tetapi tampaknya sebagian besar telah hilang. Pada saat penulisan, ini pasti ada di pohon sumber resmi OpenJDK sebagai javadoc. android.googlesource.com/platform/libcore/+/… Mungkin kita harus melaporkan bug?
Rok Kralj
Akan menjadi ide yang baik untuk melaporkan bug - perilakunya pasti tidak akan diubah, tetapi setidaknya harus didokumentasikan.
Yogu
@RokKralj Android tidak menggunakan pustaka OpenJDK, melainkan berdasarkan Apache Harmony, jadi mungkin Anda mencari di tempat yang salah?
lxgr
1
"".split (",", n)menghasilkan satu elemen array untuk n di (-1, 0, 1) dengan Oracle JDK 8. Akan menyenangkan untuk mendapatkan daftar token yang tidak kosong saja - tebak regex lengkap mungkin diperlukan (seperti "[^,\\s]+[^,]*[^,\\s]*").
simon.watts
40
Memisahkan string kosong mengembalikan string kosong sebagai elemen pertama. Jika tidak ada pembatas yang ditemukan dalam string target, Anda akan mendapatkan array berukuran 1 yang menahan string asli, meskipun kosong.
Salah. Split menghapus semua string kosong paling kanan, oleh karena itu hasilnya harus berupa array kosong. Lihat jawaban saya. ",".split(",")mengembalikan array kosong.
Salah. Split menghapus semua string kosong paling kanan, oleh karena itu hasilnya harus berupa array kosong. Lihat jawaban saya. ",".split(",")mengembalikan array kosong.
Rok Kralj
5
Dalam semua bahasa pemrograman, saya tahu string kosong masih merupakan String yang valid. Jadi melakukan pemisahan menggunakan pemisah apa pun akan selalu mengembalikan larik elemen tunggal di mana elemen itu adalah String kosong. Jika itu adalah String null (tidak kosong) maka itu akan menjadi masalah yang berbeda.
Saya pikir ini adalah fungsi perpustakaan dan bukan bagian dari bahasa. Misalnya di google guava Anda bisa menghilangkan string kosong. > Iterable <String> pieces = com.google.common.base.Splitter.on (','). OmitEmptyStrings (). Split ("");
oluies
2
Ini splitperilaku diwariskan dari Jawa, untuk lebih baik atau lebih buruk ...
Scala tidak mengesampingkan definisi dari Stringprimitif.
Parameter batas mengontrol berapa kali pola diterapkan dan karenanya memengaruhi panjang larik yang dihasilkan. Jika batas n lebih besar dari nol maka pola akan diterapkan paling banyak n - 1 kali, panjang larik tidak akan lebih dari n, dan entri terakhir larik akan berisi semua masukan di luar pembatas yang cocok terakhir. Jika n non-positif maka pola akan diterapkan sebanyak mungkin dan array dapat memiliki panjang berapa pun. Jika n adalah nol maka pola akan diterapkan sebanyak mungkin, array dapat memiliki panjang berapa pun, dan string kosong yang tertinggal akan dibuang.
yaitu Anda dapat menyetel limit=-1untuk mendapatkan perilaku (semua?) bahasa lain:
Perilaku di atas dapat diamati setidaknya dari Java 5 hingga Java 8.
Ada upaya untuk mengubah perilaku untuk mengembalikan larik kosong saat memisahkan string kosong di JDK-6559590 . Namun, itu segera dikembalikan ke JDK-8028321 ketika menyebabkan regresi di berbagai tempat. Perubahan tidak pernah membuatnya menjadi rilis awal Java 8.
Catatan: Metode pemisahan tidak ada di Java sejak awal ( bukan di 1.0.2 ) tetapi sebenarnya ada setidaknya dari 1.4 (mis. Lihat JSR51 sekitar tahun 2002). Saya masih menyelidiki ...
Apa yang tidak jelas adalah mengapa Java memilih ini di tempat pertama (kecurigaan saya adalah bahwa ini pada awalnya merupakan kekeliruan / bug dalam "kasus tepi"), tetapi sekarang dimasukkan ke dalam bahasa yang tidak dapat ditarik kembali dan tetap demikian .
Saya tidak yakin ini menjawab pertanyaan - meskipun mungkin benar untuk contoh yang diberikan di sini, itu tidak membantu dengan kasus string kosong - "".split(",")masih mengembalikan array elemen tunggal seperti [""].
DaveyDaveDave
@DaveyDaveDave itulah perilaku yang diharapkan dari setiap bahasa lain. ",,,," adalah perilaku aneh / berbeda di Scala, dan berbeda dengan kasus "".
Andy Hayden
0
String kosong tidak memiliki status khusus saat memisahkan string. Anda dapat menggunakan:
Jawaban:
Untuk alasan yang sama itu
dan
akan mengembalikan larik berukuran 2. Segala sesuatu sebelum pertandingan pertama dikembalikan sebagai elemen pertama.
sumber
"".split("wtf").length
menghasilkan 0. Hanya di JS 1.: /"," split ","
mengembalikan array 0?Jika Anda membagi jeruk nol kali, Anda mendapatkan tepat satu bagian - jeruk.
sumber
"orange".split(',')
, tetapi tidak jelas relevan untuk memisahkan string kosong. Jika saya membagi kekurangan jeruk saya nol kali, saya masih tidak memiliki jeruk; apakah kita menyatakan itu sebagai daftar kosong tanpa jeruk, daftar persis satu tidak ada jeruk, daftar dua belas tidak ada jeruk, atau apa? Ini bukan pertanyaan tentang apa yang akan kita dapatkan, tapi bagaimana kita mewakilinya.Metode pemisahan Java dan Scala beroperasi dalam dua langkah seperti ini:
",,,".split(",")
mengembalikan array kosong.Menurut ini, hasil dari
"".split(",")
harus berupa larik kosong karena langkah kedua, bukan?Itu harus. Sayangnya, ini adalah casing sudut yang diperkenalkan secara artifisial. Dan yang buruk, tapi setidaknya itu didokumentasikan dalam
java.util.regex.Pattern
, jika Anda ingat untuk melihat dokumentasi:Solusi 1: Selalu berikan -1 sebagai parameter kedua
Jadi, saya menyarankan Anda untuk selalu lulus
n == -1
sebagai parameter kedua (ini akan melewatkan langkah kedua di atas), kecuali Anda secara khusus tahu apa yang ingin Anda capai / Anda yakin bahwa string kosong bukanlah sesuatu yang akan didapat program Anda sebagai input.Solusi 2: Gunakan kelas Guava Splitter
Jika Anda sudah menggunakan Guava dalam proyek Anda, Anda dapat mencoba kelas Splitter (dokumentasi) . Ini memiliki API yang sangat kaya, dan membuat kode Anda sangat mudah dipahami.
sumber
"".split (",", n)
menghasilkan satu elemen array untuk n di (-1, 0, 1) dengan Oracle JDK 8. Akan menyenangkan untuk mendapatkan daftar token yang tidak kosong saja - tebak regex lengkap mungkin diperlukan (seperti"[^,\\s]+[^,]*[^,\\s]*"
).Memisahkan string kosong mengembalikan string kosong sebagai elemen pertama. Jika tidak ada pembatas yang ditemukan dalam string target, Anda akan mendapatkan array berukuran 1 yang menahan string asli, meskipun kosong.
sumber
",".split(",")
mengembalikan array kosong."a".split(",")
->"a"
karena itu"".split(",")
->""
sumber
",".split(",")
mengembalikan array kosong.Dalam semua bahasa pemrograman, saya tahu string kosong masih merupakan String yang valid. Jadi melakukan pemisahan menggunakan pemisah apa pun akan selalu mengembalikan larik elemen tunggal di mana elemen itu adalah String kosong. Jika itu adalah String null (tidak kosong) maka itu akan menjadi masalah yang berbeda.
sumber
Ini
split
perilaku diwariskan dari Jawa, untuk lebih baik atau lebih buruk ...Scala tidak mengesampingkan definisi dari
String
primitif.Catatan, Anda bisa menggunakan
limit
argumen untuk mengubah perilaku :yaitu Anda dapat menyetel
limit=-1
untuk mendapatkan perilaku (semua?) bahasa lain:Tampaknya terkenal bahwa perilaku Java cukup membingungkan tetapi:
Catatan: Metode pemisahan tidak ada di Java sejak awal ( bukan di 1.0.2 ) tetapi sebenarnya ada setidaknya dari 1.4 (mis. Lihat JSR51 sekitar tahun 2002). Saya masih menyelidiki ...
Apa yang tidak jelas adalah mengapa Java memilih ini di tempat pertama (kecurigaan saya adalah bahwa ini pada awalnya merupakan kekeliruan / bug dalam "kasus tepi"), tetapi sekarang dimasukkan ke dalam bahasa yang tidak dapat ditarik kembali dan tetap demikian .
sumber
"".split(",")
masih mengembalikan array elemen tunggal seperti[""]
.String kosong tidak memiliki status khusus saat memisahkan string. Anda dapat menggunakan:
sumber