Mengapa semacam mengatakan bahwa ɛ = e?


25

ɛ("Latin epsilon") adalah huruf yang digunakan dalam bahasa Afrika tertentu, biasanya untuk mewakili suara vokal dalam bahasa Inggris "bed". Di Unicode itu dikodekan sebagai U + 025B, sangat berbeda dari sehari-hari e.

Namun, jika saya sortyang berikut ini:

eb
ed
ɛa
ɛc

tampaknya sortmempertimbangkan ɛdan esetara:

ɛa
eb
ɛc
ed

Apa yang terjadi di sini? Dan adakah cara untuk membuat ɛdan emembedakan untuk sorttujuan?


21
aturan penyortiran disebut 'collation', jika itu membantu googling Anda
BlueRaja - Danny Pflughoeft

1
Cobalah untuk memasukkan sejumlah eacampuran dengan ɛadi dalam file teks dan mengurutkannya. Anda akan melihat bahwa itu selalu baik easebelumnya ɛa. Jadi, tidak mereka tidak dianggap sama.
Bakuriu

Mungkin menjadi poin yang jelas, tetapi saya belum melihatnya menyarankan secara eksplisit: jika Anda mengurutkan kata dalam $ (sure_african_language), hal alami yang harus dilakukan adalah mengatur lokal ke $ (tertentu_african_language).
Federico Poloni

@FedericoPoloni Poin yang sangat bagus! Sayangnya saya belum dapat menemukan lokal yang dibuat untuk bahasa ini.
Draconis

1
@ GermánBouzas Ini khusus "Latin epsilon", bentuk yang dirancang agar sesuai dengan alfabet Latin. Mereka terlihat hampir sama, tetapi epsilon Latin adalah U + 025B, sedangkan epsilon Yunani adalah U + 03B5.
Draconis

Jawaban:


67

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 Ememiliki berat primer yang sama, edan Eberat 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. Abmengurutkan antara aadan ac, tetapi Abdapat mengurutkan sebelum atau sesudah abtergantung pada aturan bahasa (beberapa bahasa memiliki <MIN>sebelumnya <CAP>seperti di Inggris Inggris, beberapa <CAP>sebelumnya <MIN>seperti di Estonia).

Jika ememiliki urutan pengurutan yang sama ɛ, printf '%s\n' e ɛ | sort -uakan mengembalikan hanya satu baris. Tapi seperti <BAS>sebelumnya <PCL>, esendirian juga sebelumnya ɛ . eɛemacam setelah EEE(pada berat sekunder) meskipun EEEjenis 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, lsatau gumpalan memiliki perintah non-deterministik ... ), maka rekomendasi digunakan LC_ALL=Cuntuk 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:


3
Ini persis apa yang saya cari! Untuk kelengkapan, apa artinya <PCL>? Yang lain tampaknya Capital, Miniscule, dan Basic?
Draconis

3
@Draconis, collating-symbol <PCL> # 16 particulier / aneh
Stéphane Chazelas

Memang jika kita menempatkan banyak eadan ɛatercampur menjadi satu dalam sebuah file, kita melihat sortsemua eaitu sebelumnya ɛa.
Bakuriu

2
Dari glibc 2.28, codepoint harus digunakan sebagai fallback untuk bobot level 4, lihat sourceware.org/git/… sourceware.org/bugzilla/show_bug.cgi?id=14095
ninjalj

1
@ kucing, maaf, maksud saya strcoll(), lihat edit.
Stéphane Chazelas

15

semacam pria:

   ***  WARNING  ***  The locale specified by the environment affects sort
   order.  Set LC_ALL=C to get the traditional sort order that uses native
   byte values.

Jadi, coba: LC_ALL=C sort file.txt


1
Itu bekerja! Tetapi mengapa lokal default menganggap ini sama sekali berbeda codepoint sama? Saya ingin tahu mengapa ini terjadi.
Draconis

@Draconis Apa itu "lokal default"?
Kamil Maciorowski

@KamilMaciorowski Nilai kosong dari variabel lingkungan; Saya tidak yakin lokal apa yang sesuai.
Draconis

3
@Draconis jika LC_ALLkosong, sortdapat menggunakan LC_*variabel lain , LANGatau beberapa file konfigurasi.
NieDzejkob

1
LC_COLLATEadalah string-sort-specific, LANGadalah ekstra-umum.
ShadowRanger

8

Karakter ɛ tidak sama dengan e, tetapi beberapa lokal dapat mengumpulkan tanda-tanda ini secara berdekatan pada saat pengumpulan. Alasannya spesifik bahasa, tetapi juga latar belakang sejarah atau bahkan politik. Sebagai contoh, kebanyakan orang mungkin berharap bahwa mata uang € uro mendekati Eropa dalam kamus.

Pokoknya untuk melihat susunan apa yang saat ini Anda gunakan jalankan locale, itu locale -aakan memberi Anda daftar lokal yang tersedia di sistem dan untuk mengubah susunan mengatakan Chanya untuk sekali menjalankan penyortiran LC_COLLATE=C sort file. Akhirnya untuk melihat bagaimana berbagai lokal dapat mengurutkan file Anda, cobalah

for loc in $(locale -a)
    do echo ____"${loc}"____
    LC_COLLATE="$loc" sort file
done

Pipa hasilnya ke beberapa alat bantu untuk memilih lokal yang sesuai dengan kebutuhan Anda.


Ini adalah penjelasan yang luar biasa, tetapi simbol-simbol itu tampaknya dianggap identik, bukan hanya berdekatan.
Draconis

1
Tidak, mereka tidak dianggap identik. Tambahkan eagaris polos ke file, maka dengan sort -uAnda akan mendapatkan keduanya eadan ɛadi output. Strategi terbaik vs susun adalah menghindari ( export LC_COLLATE=C). Kalau tidak, banyak hal buruk akan terjadi (mis. /tmp/[a-z]Dalam bashakan cocok /tmp/adan /tmp/Atetapi tidak /tmp/Z).
Mosvy

@mosvy Huh, menarik ... jadi mereka dianggap sama untuk tujuan pemesanan tetapi tidak untuk tujuan keunikan?
Draconis

mereka tidak dianggap sama. lihat di sini penjelasan tentang hal itu.
Mosvy

1
@ninjalj, yang mungkin diperbaiki dalam rentang glibc fnmatch()dan regexp, tetapi tidak dalam beberapa seperti bashitu mengimplementasikan rentangnya dengan sendirinya menggunakan strcoll(). ksh93 tidak pernah memiliki masalah karena implementasi jangkauannya menggunakan strcoll()dan juga memeriksa kasus ujung rentang dan hanya cocok pada karakter huruf kecil jika kedua ujungnya huruf kecil. rentang zsh tidak memiliki masalah karena dilakukan berdasarkan titik kode, bukan strcoll ().
Stéphane Chazelas
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.