Saya menggunakan bash di Linux. Saya mendapatkan kesuksesan dari pernyataan if berikut ini, tetapi tidakkah ini menghasilkan kode gagal?
if [[ ■ = [⅕⅖⅗] ]] ; then echo yes ; fi
Alun-alun BUKAN sama dengan salah satu karakter, jadi saya tidak melihat mengapa saya mendapatkan kode sukses.
Penting bagi saya untuk menyimpan kurung ganda dalam kasus saya.
Apakah ada cara lain untuk melakukan rentang dalam skenario ini, atau apa saran lainnya?
C
tidak akan dilakukan di sini karena ini bukan karakter byte tunggal.C.UTF-8
akan dilakukan jika tersedia.Jawaban:
Itu konsekuensi dari karakter-karakter yang memiliki urutan penyortiran yang sama.
Anda juga akan memperhatikan itu
mengembalikan hanya satu baris.
Atau itu:
mengembalikan true (seperti yang disyaratkan oleh POSIX).
Sebagian besar lokal yang dikirimkan dengan sistem GNU memiliki sejumlah karakter (dan bahkan urutan karakter (susun urutan)) yang memiliki urutan penyortiran yang sama. Dalam kasus orang-orang ■ itu, itu karena urutannya tidak ditentukan, dan karakter-karakter yang urutannya tidak didefinisikan pada akhirnya memiliki urutan penyortiran yang sama dalam sistem GNU. Ada karakter yang secara eksplisit didefinisikan sebagai memiliki urutan penyortiran yang sama seperti Ș dan Ş (meskipun tidak ada logika nyata atau konsistensi tentang bagaimana hal itu dilakukan).
Itulah sumber perilaku yang cukup mengejutkan dan palsu. Saya telah mengangkat masalah ini baru-baru ini di milis Austin (badan di belakang POSIX dan Spesifikasi UNIX Tunggal) dan diskusi masih berlangsung hingga 2015-04-03.
Dalam hal ini, apakah
[y]
harus cocok dengan dix
manax
dany
mengurutkan yang sama tidak jelas bagi saya, tetapi karena ekspresi braket dimaksudkan untuk mencocokkan elemen penyusun, itu menunjukkan bahwabash
perilaku tersebut diharapkan.Bagaimanapun, saya kira
[⅕-⅕]
atau setidaknya[⅕-⅖]
harus cocok■
.Anda akan melihat bahwa berbagai alat berperilaku berbeda. ksh93 berperilaku seperti
bash
, GNUgrep
ataused
tidak. Beberapa cangkang lain memiliki perilaku yang berbeda, beberapayash
bahkan lebih buggy.Untuk memiliki perilaku yang konsisten, Anda memerlukan lokal di mana semua karakter diurutkan secara berbeda. C locale adalah yang khas. Namun karakter yang ditetapkan di C locale pada kebanyakan sistem adalah ASCII. Pada sistem GNU, Anda biasanya memiliki akses ke
C.UTF-8
lokal yang dapat digunakan untuk bekerja pada karakter UTF-8.Begitu:
atau standar yang setara:
harus mengembalikan false.
Alternatif lain adalah dengan menetapkan hanya
LC_COLLATE
untuk C yang akan bekerja pada sistem GNU, tetapi tidak harus pada yang lain di mana ia bisa gagal untuk menentukan urutan penyortiran karakter multi-byte.Satu pelajaran tentang hal itu adalah bahwa kesetaraan tidak sejelas gagasan seperti yang diharapkan orang ketika membandingkan string. Kesetaraan mungkin berarti, dari yang paling ketat hingga yang paling tidak ketat.
Sekarang, untuk 2 atau 3, yang mengasumsikan kedua string berisi karakter yang valid. Dalam UTF-8 dan beberapa pengkodean lainnya, beberapa urutan byte tidak membentuk karakter yang valid.
1 dan 2 tidak harus sama karena itu, atau karena beberapa karakter mungkin memiliki lebih dari satu kemungkinan penyandian. Itu biasanya kasus pengkodean stateful seperti ISO-2022-JP di mana
A
dapat dinyatakan sebagai41
atau1b 28 42 41
(1b 28 42
menjadi urutan untuk beralih ke ASCII dan Anda dapat memasukkan sebanyak yang Anda inginkan, yang tidak akan membuat perbedaan), meskipun saya tidak akan mengharapkan jenis-jenis penyandian itu masih digunakan, dan alat-alat GNU setidaknya secara umum tidak bekerja dengan benar.Berhati-hatilah karena sebagian besar utilitas non-GNU tidak dapat menangani nilai 0 byte (karakter NUL di ASCII).
Mana yang definisi yang digunakan tergantung pada utilitas dan utilitas implementasi atau versi. POSIX tidak 100% jelas tentang hal itu. Di C locale, ketiganya setara. Di luar YMMV itu.
sumber
é
dané
menjadi string yang sama, tetapi tidake
. Gagasan POSIX tentang susunan kolase jarang benar, terlalu berat berdasarkan karakter dan tidak menjelaskan cara penyortiran string yang paling umum (misalnya kamus Prancis tidak menggunakan urutan leksikografis untuk mengurutkan kata-kata: mereka melakukan leksikografi pertama dengan aksen diabaikan dan kemudian gunakan aksen untuk memutuskan ikatan).Anda salah melakukannya,
=
dan==
tidak sama.Coba contoh ini:
sumber
=
harus digunakan untuk memeriksa kesetaraan. Masalahnya adalah kutipan yang hilang, bukan operator.man bash
mengatakan di[[
bagian: "Operator = setara dengan ==."[[...]]
operator. Dan = dan == sama di shell jika itu diterapkan (ksh / bash / zsh) dan untuk pencocokan pola, bukan kesetaraan.