Tidak, itu tidak menganggap mereka setara, mereka hanya memiliki berat primer yang sama. Sehingga, pada pendekatan pertama, mereka mengurutkan sama.
Jika Anda melihat / usr / share / i18n / locales / iso14651_t1_common (seperti yang digunakan sebagai dasar untuk sebagian besar lokal) pada sistem GNU (di sini dengan glibc 2.27), Anda akan melihat:
<U0065> <e>;<BAS>;<MIN>;IGNORE # 259 e
<U025B> <e>;<PCL>;<MIN>;IGNORE # 287 ɛ
<U0045> <e>;<BAS>;<CAP>;IGNORE # 577 E
e
, ɛ
dan E
memiliki berat primer yang sama, e
dan E
berat sekunder yang sama, hanya berat ketiga yang membedakannya.
Saat membandingkan string, sort
( strcoll()
fungsi libc standar digunakan untuk membandingkan string) dimulai dengan membandingkan bobot primer semua karakter, dan hanya berlaku untuk bobot kedua jika string sama dengan bobot primer (dan seterusnya dengan bobot lainnya) .
Begitulah kasus tampaknya diabaikan dalam urutan penyortiran dalam perkiraan pertama. Ab
mengurutkan antara aa
dan ac
, tetapi Ab
dapat mengurutkan sebelum atau sesudah ab
tergantung pada aturan bahasa (beberapa bahasa memiliki <MIN>
sebelumnya <CAP>
seperti di Inggris Inggris, beberapa <CAP>
sebelumnya <MIN>
seperti di Estonia).
Jika e
memiliki urutan pengurutan yang sama ɛ
, printf '%s\n' e ɛ | sort -u
akan mengembalikan hanya satu baris. Tapi seperti <BAS>
sebelumnya <PCL>
, e
sendirian juga sebelumnya ɛ
. eɛe
macam setelah EEE
(pada berat sekunder) meskipun EEE
jenis setelah eee
(yang kita perlu naik ke berat ketiga).
Sekarang jika pada sistem saya dengan glibc 2.27, saya menjalankan:
sed -n 's/\(.*;[^[:blank:]]*\).*/\1/p' /usr/share/i18n/locales/iso14651_t1_common |
sort -k2 | uniq -Df1
Anda akan melihat bahwa ada beberapa karakter yang telah ditentukan dengan 4 bobot yang sama persis. Secara khusus, ɛ kami memiliki bobot yang sama dengan:
<U01DD> <e>;<PCL>;<MIN>;IGNORE
<U0259> <e>;<PCL>;<MIN>;IGNORE
<U025B> <e>;<PCL>;<MIN>;IGNORE
Dan tentu saja:
$ printf '%s\n' $'\u01DD' $'\u0259' $'\u025B' | sort -u
ǝ
$ expr ɛ = ǝ
1
Itu bisa dilihat sebagai bug dari local libc GNU. Pada kebanyakan sistem lain, lokal memastikan semua karakter yang berbeda memiliki urutan penyortiran yang berbeda pada akhirnya. Pada lokal GNU, mendapatkan bahkan lebih buruk, karena ada ribuan karakter yang tidak memiliki urutan menyortir dan berakhir menyortir sama, menyebabkan segala macam masalah (seperti melanggar comm
, join
, ls
atau gumpalan memiliki perintah non-deterministik ... ), maka rekomendasi digunakan LC_ALL=C
untuk mengatasi masalah tersebut .
Seperti dicatat oleh @ninjalj dalam komentar, glibc 2.28 dirilis pada Agustus 2018 datang dengan beberapa perbaikan di bagian depan itu meskipun AFAICS, masih ada beberapa karakter atau elemen penyusun yang didefinisikan dengan urutan penyortiran yang identik. Di Ubuntu 18.10 dengan glibc 2.28 dan di lokal en_GB.UTF-8.
$ expr $'L\ub7' = $'L\u387'
1
(mengapa U + 00B7 dianggap setara dengan U + 0387 hanya jika dikombinasikan dengan L
/ l
?!).
Dan:
$ perl -lC -e 'for($i=0; $i<0x110000; $i++) {$i = 0xe000 if $i == 0xd800; print chr($i)}' | sort > all-chars-sorted
$ uniq -d all-chars-sorted | wc -l
4
$ uniq -D all-chars-sorted | wc -l
1061355
(masih lebih dari 1 juta karakter (95% dari kisaran Unicode, turun dari 98% di 2,27) menyortir sama dengan karakter lain karena urutan penyortirannya tidak ditentukan).
Lihat juga: