Không, nó không coi chúng là tương đương, chúng chỉ có cùng trọng lượng chính. Vì vậy, trong xấp xỉ đầu tiên, họ sắp xếp giống nhau.
Nếu bạn xem / usr / share / i18n / loc / iso14651_t1_common (làm cơ sở cho hầu hết các địa phương) trên hệ thống GNU (ở đây với glibc 2.27), bạn sẽ thấy:
<U0065> <e>;<BAS>;<MIN>;IGNORE # 259 e
<U025B> <e>;<PCL>;<MIN>;IGNORE # 287 ɛ
<U0045> <e>;<BAS>;<CAP>;IGNORE # 577 E
e
, ɛ
Và E
có trọng lượng sơ cấp như nhau, e
và E
trọng lượng thứ cấp tương tự, chỉ có trọng lượng thứ ba phân biệt chúng.
Khi so sánh các chuỗi, sort
( strcoll()
hàm libc tiêu chuẩn được sử dụng để so sánh các chuỗi) bắt đầu bằng cách so sánh các trọng số chính của tất cả các ký tự và chỉ đi theo trọng số thứ hai nếu các chuỗi bằng với các trọng số chính (v.v. với các trọng số khác) .
Đó là cách trường hợp dường như bị bỏ qua theo thứ tự sắp xếp trong xấp xỉ đầu tiên. Ab
sắp xếp giữa aa
và ac
, nhưng Ab
có thể sắp xếp trước hoặc sau ab
tùy thuộc vào quy tắc ngôn ngữ (một số ngôn ngữ có <MIN>
trước <CAP>
giống như trong tiếng Anh Anh, một số <CAP>
trước <MIN>
như ở tiếng Estonia).
Nếu e
có cùng thứ tự sắp xếp như ɛ
, printf '%s\n' e ɛ | sort -u
sẽ chỉ trả về một dòng. Nhưng như <BAS>
sắp xếp trước <PCL>
, e
một mình sắp xếp trước ɛ
. eɛe
sắp xếp sau EEE
(ở trọng lượng thứ cấp) mặc dù EEE
sắp xếp sau eee
(mà chúng ta cần tăng lên trọng lượng thứ ba).
Bây giờ nếu trên hệ thống của tôi với glibc 2.27, tôi chạy:
sed -n 's/\(.*;[^[:blank:]]*\).*/\1/p' /usr/share/i18n/locales/iso14651_t1_common |
sort -k2 | uniq -Df1
Bạn sẽ nhận thấy rằng có khá nhiều ký tự đã được xác định với cùng 4 trọng số. Cụ thể, của chúng tôi có cùng trọng số như:
<U01DD> <e>;<PCL>;<MIN>;IGNORE
<U0259> <e>;<PCL>;<MIN>;IGNORE
<U025B> <e>;<PCL>;<MIN>;IGNORE
Và chắc chắn:
$ printf '%s\n' $'\u01DD' $'\u0259' $'\u025B' | sort -u
ǝ
$ expr ɛ = ǝ
1
Đó có thể được coi là một lỗi của GNU libc local. Trên hầu hết các hệ thống khác, các địa phương đảm bảo rằng tất cả các ký tự khác nhau có thứ tự sắp xếp khác nhau cuối cùng. Trên miền địa phương GNU, nó được thậm chí tệ hơn, như có hàng ngàn nhân vật mà không có một trật tự sắp xếp và kết thúc sắp xếp giống nhau, khiến cho tất cả các loại của các vấn đề (như phá vỡ comm
, join
, ls
hoặc những đống có đơn đặt hàng không xác định ... ), do đó khuyến nghị sử dụng LC_ALL=C
để giải quyết những vấn đề đó .
Theo ghi nhận của @ninjalj trong các bình luận, glibc 2.28 được phát hành vào tháng 8 năm 2018 đi kèm với một số cải tiến trên mặt trận đó mặc dù AFAICS, vẫn còn một số ký tự hoặc các yếu tố đối chiếu được xác định theo thứ tự sắp xếp giống hệt nhau. Trên Ubuntu 18.10 với glibc 2.28 và trong miền địa phương en_GB.UTF-8.
$ expr $'L\ub7' = $'L\u387'
1
(tại sao U + 00B7 chỉ được coi là tương đương với U + 0387 khi kết hợp với L
/ l
?!).
Và:
$ 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
(vẫn còn hơn 1 triệu ký tự (95% phạm vi Unicode, giảm từ 98% trong 2,27) sắp xếp giống như các ký tự khác khi thứ tự sắp xếp của chúng không được xác định).
Xem thêm: