SOLUSI AKHIR YANG MUNGKIN
Jadi saya telah mengambil semua informasi di bawah ini dan menghasilkan ini:
for class in $(
locale -v LC_CTYPE |
sed 's/combin.*//;s/;/\n/g;q'
) ; do
printf "\n\t%s\n\n" $class
recode u2/test16 -q </dev/null |
tr -dc "[:$class:]" |
od -A n -t a -t o1z -w12
done
CATATAN :
Saya menggunakan odsebagai filter terakhir di atas untuk preferensi dan karena saya tahu saya tidak akan bekerja dengan karakter multi-byte, yang tidak akan ditangani dengan benar. recode u2..dumpkeduanya akan menghasilkan keluaran lebih seperti yang ditentukan dalam pertanyaan dan menangani karakter lebar dengan benar.
KELUARAN
upper
A B C D E F G H I J K L
101 102 103 104 105 106 107 110 111 112 113 114 >ABCDEFGHIJKL<
M N O P Q R S T U V W X
115 116 117 120 121 122 123 124 125 126 127 130 >MNOPQRSTUVWX<
Y Z
131 132 >YZ<
lower
a b c d e f g h i j k l
141 142 143 144 145 146 147 150 151 152 153 154 >abcdefghijkl<
m n o p q r s t u v w x
155 156 157 160 161 162 163 164 165 166 167 170 >mnopqrstuvwx<
y z
171 172 >yz<
alpha
A B C D E F G H I J K L
101 102 103 104 105 106 107 110 111 112 113 114 >ABCDEFGHIJKL<
M N O P Q R S T U V W X
115 116 117 120 121 122 123 124 125 126 127 130 >MNOPQRSTUVWX<
Y Z a b c d e f g h i j
131 132 141 142 143 144 145 146 147 150 151 152 >YZabcdefghij<
k l m n o p q r s t u v
153 154 155 156 157 160 161 162 163 164 165 166 >klmnopqrstuv<
w x y z
167 170 171 172 >wxyz<
digit
0 1 2 3 4 5 6 7 8 9
060 061 062 063 064 065 066 067 070 071 >0123456789<
xdigit
0 1 2 3 4 5 6 7 8 9 A B
060 061 062 063 064 065 066 067 070 071 101 102 >0123456789AB<
C D E F a b c d e f
103 104 105 106 141 142 143 144 145 146 >CDEFabcdef<
space
ht nl vt ff cr sp
011 012 013 014 015 040 >..... <
print
sp ! " # $ % & ' ( ) * +
040 041 042 043 044 045 046 047 050 051 052 053 > !"#$%&'()*+<
, - . / 0 1 2 3 4 5 6 7
054 055 056 057 060 061 062 063 064 065 066 067 >,-./01234567<
8 9 : ; < = > ? @ A B C
070 071 072 073 074 075 076 077 100 101 102 103 >89:;<=>?@ABC<
D E F G H I J K L M N O
104 105 106 107 110 111 112 113 114 115 116 117 >DEFGHIJKLMNO<
P Q R S T U V W X Y Z [
120 121 122 123 124 125 126 127 130 131 132 133 >PQRSTUVWXYZ[<
\ ] ^ _ ` a b c d e f g
134 135 136 137 140 141 142 143 144 145 146 147 >\]^_`abcdefg<
h i j k l m n o p q r s
150 151 152 153 154 155 156 157 160 161 162 163 >hijklmnopqrs<
t u v w x y z { | } ~
164 165 166 167 170 171 172 173 174 175 176 >tuvwxyz{|}~<
graph
! " # $ % & ' ( ) * + ,
041 042 043 044 045 046 047 050 051 052 053 054 >!"#$%&'()*+,<
- . / 0 1 2 3 4 5 6 7 8
055 056 057 060 061 062 063 064 065 066 067 070 >-./012345678<
9 : ; < = > ? @ A B C D
071 072 073 074 075 076 077 100 101 102 103 104 >9:;<=>?@ABCD<
E F G H I J K L M N O P
105 106 107 110 111 112 113 114 115 116 117 120 >EFGHIJKLMNOP<
Q R S T U V W X Y Z [ \
121 122 123 124 125 126 127 130 131 132 133 134 >QRSTUVWXYZ[\<
] ^ _ ` a b c d e f g h
135 136 137 140 141 142 143 144 145 146 147 150 >]^_`abcdefgh<
i j k l m n o p q r s t
151 152 153 154 155 156 157 160 161 162 163 164 >ijklmnopqrst<
u v w x y z { | } ~
165 166 167 170 171 172 173 174 175 176 >uvwxyz{|}~<
blank
ht sp
011 040 >. <
cntrl
nul soh stx etx eot enq ack bel bs ht nl vt
000 001 002 003 004 005 006 007 010 011 012 013 >............<
ff cr so si dle dc1 dc2 dc3 dc4 nak syn etb
014 015 016 017 020 021 022 023 024 025 026 027 >............<
can em sub esc fs gs rs us del
030 031 032 033 034 035 036 037 177 >.........<
punct
! " # $ % & ' ( ) * + ,
041 042 043 044 045 046 047 050 051 052 053 054 >!"#$%&'()*+,<
- . / : ; < = > ? @ [ \
055 056 057 072 073 074 075 076 077 100 133 134 >-./:;<=>?@[\<
] ^ _ ` { | } ~
135 136 137 140 173 174 175 176 >]^_`{|}~<
alnum
0 1 2 3 4 5 6 7 8 9 A B
060 061 062 063 064 065 066 067 070 071 101 102 >0123456789AB<
C D E F G H I J K L M N
103 104 105 106 107 110 111 112 113 114 115 116 >CDEFGHIJKLMN<
O P Q R S T U V W X Y Z
117 120 121 122 123 124 125 126 127 130 131 132 >OPQRSTUVWXYZ<
a b c d e f g h i j k l
141 142 143 144 145 146 147 150 151 152 153 154 >abcdefghijkl<
m n o p q r s t u v w x
155 156 157 160 161 162 163 164 165 166 167 170 >mnopqrstuvwx<
y z
API PROGRAMMER
Seperti yang saya tunjukkan di bawah, recodeakan memberi Anda peta karakter lengkap Anda. Menurut manualnya, ia melakukan ini pertama sesuai dengan nilai saat ini dari DEFAULT_CHARSETvariabel lingkungan, atau, jika gagal, ia beroperasi persis seperti yang Anda tentukan:
Ketika nama rangkaian karakter dihilangkan atau dibiarkan kosong, nilai DEFAULT_CHARSETvariabel dalam lingkungan digunakan sebagai gantinya. Jika variabel ini tidak didefinisikan, recodeperpustakaan menggunakan pengkodean lokal saat ini. Pada sistem yang mendukung POSIX , ini tergantung pada nilai non-kosong pertama di antara variabel lingkungan LC_ALL, LC_CTYPE, LANGdan dapat ditentukan melalui perintahlocale charmap.
Juga perlu diperhatikan recodeadalah bahwa ini adalah api :
Program bernama recodehanyalah aplikasi perpustakaan pengodeannya. Perpustakaan pengodean ulang tersedia secara terpisah untuk program C lainnya. Cara yang baik untuk mendapatkan keakraban dengan perpustakaan pengodean ulang adalah untuk berkenalan dengan recodeprogram itu sendiri.
Untuk menggunakan perpustakaan pengodean ulang setelah diinstal, program C perlu memiliki baris:
#include <recode.h>
Untuk perbandingan string yang ramah internasional POSIXdan Cstandar mendefinisikan strcoll()fungsi:
The strcoll()Fungsi akan membandingkan string ditunjukkan oleh s1ke string yang ditunjukkan oleh s2, baik ditafsirkan sesuai dengan kategori LC_COLLATE dari lokal saat ini.
The strcoll()Fungsi tidak akan mengubah pengaturan errno jika berhasil.
Karena tidak ada nilai balik yang dicadangkan untuk menunjukkan kesalahan, aplikasi yang ingin memeriksa situasi kesalahan harus menetapkan errno ke 0, lalu panggil
strcoll(), lalu periksa errno.
Berikut ini adalah secara terpisah terletak contoh penggunaannya:
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[15];
char str2[15];
int ret;
strcpy(str1, "abc");
strcpy(str2, "ABC");
ret = strcoll(str1, str2);
if(ret > 0)
{
printf("str1 is less than str2");
}
else if(ret < 0)
{
printf("str2 is less than str1");
}
else
{
printf("str1 is equal to str2");
}
return(0);
}
Mengenai POSIXkelas karakter, Anda telah mencatat Anda menggunakan CAPI untuk menemukannya. Untuk karakter dan kelas unicode Anda bisa menggunakan charset recode's dump-with-names untuk mendapatkan hasil yang diinginkan. Dari manualnya lagi :
Misalnya, perintah tersebut recode l2..full < inputmenyiratkan konversi yang diperlukan dari Latin-2 ke UCS-2, karena dump-with-names hanya terhubung dari UCS-2. Dalam kasus tersebut, recodetidak menampilkan kode
Latin-2 asli di dump, hanya nilai UCS-2 yang sesuai . Untuk memberikan contoh yang lebih sederhana, perintah
echo 'Hello, world!' | recode us..dump
menghasilkan output berikut:
UCS2 Mne Description
0048 H latin capital letter h
0065 e latin small letter e
006C l latin small letter l
006C l latin small letter l
006F o latin small letter o
002C , comma
0020 SP space
0077 w latin small letter w
006F o latin small letter o
0072 r latin small letter r
006C l latin small letter l
0064 d latin small letter d
0021 ! exclamation mark
000A LF line feed (lf)
Komentar deskriptif diberikan dalam bahasa Inggris dan ASCII, namun jika deskripsi bahasa Inggris tidak tersedia tetapi yang Prancis, maka deskripsi Perancis diberikan sebagai gantinya, menggunakan bahasa Latin-1. Namun, jika
variabel LANGUAGEatau LANGlingkungan dimulai dengan huruf fr , maka daftar preferensi akan ke Prancis ketika kedua deskripsi tersedia.
Menggunakan sintaksis yang mirip dengan yang di atas dikombinasikan dengan dataset tes yang disertakan saya bisa mendapatkan peta karakter saya sendiri dengan:
recode -q u8/test8..dump </dev/null
KELUARAN
UCS2 Mne Description
0001 SH start of heading (soh)
0002 SX start of text (stx)
0003 EX end of text (etx)
...
002B + plus sign
002C , comma
002D - hyphen-minus
...
0043 C latin capital letter c
0044 D latin capital letter d
0045 E latin capital letter e
...
006B k latin small letter k
006C l latin small letter l
006D m latin small letter m
...
007B (! left curly bracket
007C !! vertical line
007D !) right curly bracket
007E '? tilde
007F DT delete (del)
Tetapi untuk karakter umum, recodetampaknya tidak perlu. Ini akan memberi Anda charset bernama untuk semua yang ada di charset 128 byte:
printf %b "$(printf \\%04o $(seq 128))" |
luit -c |
od -A n -t o1z -t a -w12
KELUARAN
001 002 003 004 005 006 007 010 011 012 013 014 >............<
soh stx etx eot enq ack bel bs ht nl vt ff
...
171 172 173 174 175 176 177 >yz{|}~.<
y z { | } ~ del
Tentu saja, hanya 128-byte yang diwakili, tetapi itu karena lokal saya, utf-8 charmaps atau tidak, menggunakan charset ASCII dan tidak lebih. Jadi hanya itu yang saya dapat. Jika saya menjalankannya tanpa luitmenyaringnya, odakan menggulungnya kembali dan mencetak peta yang sama lagi\0400.
Ada dua masalah utama dengan metode di atas. Pertama, ada susunan susunan sistem - untuk non-ASCII lokal nilai-nilai gigitan untuk rangkaian tidak hanya seqmempengaruhi, yang, seperti yang saya pikirkan, kemungkinan merupakan inti dari masalah yang Anda coba selesaikan.
Yah, tr's manhalaman GNU menyatakan bahwa itu akan memperluas [:upper:] [:lower:]kelas secara berurutan - tapi itu tidak banyak.
Saya membayangkan beberapa solusi yang berat dapat diimplementasikan dengan sorttetapi itu akan menjadi alat yang agak sulit untuk API pemrograman backend.
recodeakan melakukan hal ini dengan benar, tetapi Anda sepertinya tidak terlalu menyukai program tersebut tempo hari. Mungkin suntingan hari ini akan memberikan cahaya yang lebih bersahabat atau mungkin tidak.
GNU juga menawarkan gettextfungsi perpustakaan, dan tampaknya mampu mengatasi masalah ini setidaknya untuk LC_MESSAGESkonteksnya:
- Fungsi: char * bind_textdomain_codeset( const char *domainname,
const char *codeset)
The bind_textdomain_codesetfungsi dapat digunakan untuk menentukan set karakter output untuk pesan katalog untuk domain
domainname . The codeset Argumen harus valid codeset nama yang dapat digunakan untuk iconv_open fungsi, atau null pointer.
Jika parameter codeset adalah penunjuk nol, bind_textdomain_codeset
mengembalikan set kode yang saat ini dipilih untuk domain dengan nama
domainname . Ia mengembalikan NULL jika tidak ada kode yang dipilih.
The bind_textdomain_codesetfungsi dapat digunakan beberapa kali. Jika digunakan beberapa kali dengan argumen domainname yang sama, panggilan selanjutnya menimpa pengaturan yang dibuat oleh yang sebelumnya.
The bind_textdomain_codesetmengembalikan fungsi pointer ke string yang berisi nama codeset yang dipilih. String dialokasikan secara internal dalam fungsi dan tidak boleh diubah oleh pengguna. Jika sistem keluar dari inti selama eksekusi
bind_textdomain_codeset, nilai kembali adalah NULL dan errno variabel global diatur sesuai.
Anda juga dapat menggunakan kategori karakter Unicode asli , yang independen terhadap bahasa dan melepaskan kelas POSIX, atau mungkin memanggil yang pertama untuk memberi Anda cukup informasi untuk mendefinisikan yang terakhir.
Selain komplikasi, Unicode juga membawa kemungkinan baru. Salah satunya adalah bahwa setiap karakter Unicode milik kategori tertentu . Anda dapat mencocokkan satu karakter yang termasuk dalam kategori "huruf" dengan
\p{L}. Anda dapat mencocokkan satu karakter yang tidak termasuk dalam kategori itu \P{L}.
Sekali lagi, "karakter" benar-benar berarti "titik kode Unicode". \p{L}cocok dengan satu titik kode dalam kategori "huruf". Jika string input Anda à
dikodekan sebagai U+0061 U+0300, string tersebut cocok atanpa aksen. Jika input àdikodekan sebagai U+00E0, itu cocok àdengan aksen. Alasannya adalah bahwa kedua kode menunjuk U+0061 (a)dan U+00E0 (à)berada dalam kategori "huruf", sedangkan U+0300berada dalam kategori "tanda".
Anda sekarang harus mengerti mengapa \P{M}\p{M}*+itu setara dengan \X.
\P{M}cocok dengan titik kode yang bukan tanda menggabungkan, sedangkan \p{M}*+
cocok dengan nol atau lebih titik kode yang menggabungkan tanda. Untuk mencocokkan surat termasuk diakritik, gunakan \p{L}\p{M}*+. Regex terakhir ini akan selalu cocok à, terlepas dari bagaimana dikodekan. Kuantif posesif memastikan bahwa menelusuri kembali tidak menyebabkan \P{M}\p{M}*+mencocokkan non-mark tanpa menggabungkan tanda yang mengikutinya, yang \X
tidak akan pernah berhasil.
Website yang sama yang memberikan informasi atas juga membahas Tclsendiri 's POSIX compliant implementasi regex yang mungkin cara lain untuk mencapai tujuan Anda.
Dan yang terakhir di antara solusi saya akan menyarankan agar Anda dapat menginterogasi LC_COLLATEfile itu sendiri untuk peta karakter sistem lengkap dan teratur . Ini mungkin tampaknya tidak mudah dilakukan, tetapi saya mencapai beberapa keberhasilan dengan yang berikut setelah mengkompilasinya localedefseperti yang ditunjukkan di bawah ini:
<LC_COLLATE od -j2K -a -w2048 -v |
tail -n2 |
cut -d' ' -f$(seq -s',' 4 2 2048) |
sed 's/nul\|\\0//g;s/ */ /g;:s;
s/\([^ ]\{1,3\}\) \1/\1/;ts;
s/\(\([^ ][^ ]* *\)\{16\}\)/\1\n/g'
dc1 dc2 dc3 dc4 nak syn etb can c fs c rs c sp ! "
# $ % & ' ( ) * + , - . / 0 1 2
3 4 5 6 7 8 9 : ; < = > ? @ A B
C D E F G H I J K L M N O P Q R
S T U V W X Y Z [ \ ] ^ _ ` a b
c d e f g h i j k l m n o p q r
s t u v w x y z { | } ~ del soh stx etx
eot enq ack bel c ht c vt cr c si dle dc1 del
Memang, saat ini, cacat, tapi saya harap itu menunjukkan kemungkinan setidaknya.
DI BLUSH PERTAMA
strings $_/en_GB
#OUTPUT
int_select "<U0030><U0030>"
...
END LC_TELEPHONE
Itu benar-benar tidak terlihat banyak tetapi kemudian saya mulai memperhatikan copyperintah di seluruh daftar. File di atas tampaknya copydi "en_US" misalnya, dan satu lagi yang benar-benar besar yang tampaknya mereka semua bagikan pada tingkat tertentu iso_14651_t1_common.
Cukup besar:
strings $_ | wc -c
#OUTPUT
431545
Inilah intro untuk /usr/share/i18n/locales/POSIX:
# Territory:
# Revision: 1.1
# Date: 1997-03-15
# Application: general
# Users: general
# Repertoiremap: POSIX
# Charset: ISO646:1993
# Distribution and use is free, also for
# commercial purposes.
LC_CTYPE
# The following is the POSIX Locale LC_CTYPE.
# "alpha" is by default "upper" and "lower"
# "alnum" is by definiton "alpha" and "digit"
# "print" is by default "alnum", "punct" and the <U0020> character
# "graph" is by default "alnum" and "punct"
upper <U0041>;<U0042>;<U0043>;<U0044>;<U0045>;<U0046>;<U0047>;<U0048>;\
<U0049>;<U004A>;<U004B>;<U004C>;<U004D>;<U004E>;<U004F>;
...
Anda dapat grepmelalui ini tentu saja, tetapi Anda mungkin hanya:
recode -lf gb
Sebagai gantinya. Anda akan mendapatkan sesuatu seperti ini:
Dec Oct Hex UCS2 Mne BS_4730
0 000 00 0000 NU null (nul)
1 001 01 0001 SH start of heading (soh)
...
... DAN LEBIH BANYAK
Ada juga perangkat terjemahan luitterminal UTF-8 yang ptysaya kira berfungsi sebagai perantara untuk XTerms tanpa dukungan UTF-8. Ini menangani banyak switch - seperti mencatat semua byte yang dikonversi ke file atau -csebagai |pipefilter sederhana .
Saya tidak pernah menyadari ada begitu banyak hal ini - peta karakter dan lokal dan semua itu. Ini tampaknya masalah yang sangat besar tapi saya kira itu semua terjadi di belakang layar. Ada - setidaknya di sistem saya - beberapa ratus man 3hasil terkait untuk pencarian terkait lokal.
Dan juga ada:
zcat /usr/share/i18n/charmaps/UTF-8*gz | less
CHARMAP
<U0000> /x00 NULL
<U0001> /x01 START OF HEADING
<U0002> /x02 START OF TEXT
<U0003> /x03 END OF TEXT
<U0004> /x04 END OF TRANSMISSION
<U0005> /x05 ENQUIRY
...
Itu akan berlangsung untuk waktu yang sangat lama.
The Xlibfungsi menangani ini semua waktu - luitadalah bagian dari paket itu.
The Tcl_uni...fungsi mungkin terbukti bermanfaat juga.
hanya sedikit <tab>penyelesaian dan manpencarian dan saya sudah belajar banyak tentang hal ini.
Dengan localedef- Anda dapat mengkompilasi localesdalam I18Ndirektori Anda . Outputnya funky, dan tidak terlalu berguna - tidak seperti charmapssama sekali - tetapi Anda bisa mendapatkan format mentah seperti yang Anda tentukan di atas seperti yang saya lakukan:
mkdir -p dir && cd $_ ; localedef -f UTF-8 -i en_GB ./
ls -l
total 1508
drwxr-xr-x 1 mikeserv mikeserv 30 May 6 18:35 LC_MESSAGES
-rw-r--r-- 1 mikeserv mikeserv 146 May 6 18:35 LC_ADDRESS
-rw-r--r-- 1 mikeserv mikeserv 1243766 May 6 18:35 LC_COLLATE
-rw-r--r-- 1 mikeserv mikeserv 256420 May 6 18:35 LC_CTYPE
-rw-r--r-- 1 mikeserv mikeserv 376 May 6 18:35 LC_IDENTIFICATION
-rw-r--r-- 1 mikeserv mikeserv 23 May 6 18:35 LC_MEASUREMENT
-rw-r--r-- 1 mikeserv mikeserv 290 May 6 18:35 LC_MONETARY
-rw-r--r-- 1 mikeserv mikeserv 77 May 6 18:35 LC_NAME
-rw-r--r-- 1 mikeserv mikeserv 54 May 6 18:35 LC_NUMERIC
-rw-r--r-- 1 mikeserv mikeserv 34 May 6 18:35 LC_PAPER
-rw-r--r-- 1 mikeserv mikeserv 56 May 6 18:35 LC_TELEPHONE
-rw-r--r-- 1 mikeserv mikeserv 2470 May 6 18:35 LC_TIME
Kemudian dengan odAnda dapat membacanya - byte dan string:
od -An -a -t u1z -w12 LC_COLLATE | less
etb dle enq sp dc3 nul nul nul T nul nul nul
23 16 5 32 19 0 0 0 84 0 0 0 >... ....T...<
...
Meskipun masih jauh dari memenangkan kontes kecantikan, itu adalah hasil yang dapat digunakan. Dan oddapat dikonfigurasi seperti yang Anda inginkan juga, tentu saja.
Saya kira saya juga lupa tentang ini:
perl -mLocale
-- Perl module --
Locale::Codes Locale::Codes::LangFam Locale::Codes::Script_Retired
Locale::Codes::Constants Locale::Codes::LangFam_Codes Locale::Country
Locale::Codes::Country Locale::Codes::LangFam_Retired Locale::Currency
Locale::Codes::Country_Codes Locale::Codes::LangVar Locale::Language
Locale::Codes::Country_Retired Locale::Codes::LangVar_Codes Locale::Maketext
Locale::Codes::Currency Locale::Codes::LangVar_Retired Locale::Maketext::Guts
Locale::Codes::Currency_Codes Locale::Codes::Language Locale::Maketext::GutsLoader
Locale::Codes::Currency_Retired Locale::Codes::Language_Codes Locale::Maketext::Simple
Locale::Codes::LangExt Locale::Codes::Language_Retired Locale::Script
Locale::Codes::LangExt_Codes Locale::Codes::Script Locale::gettext
Locale::Codes::LangExt_Retired Locale::Codes::Script_Codes locale
Saya mungkin lupa tentang mereka karena saya tidak bisa membuatnya bekerja. Saya tidak pernah menggunakan Perldan saya tidak tahu cara memuat modul dengan benar saya kira. Tapi manhalaman - halamannya terlihat cukup bagus. Bagaimanapun, ada sesuatu yang memberitahu saya Anda akan menemukan memanggil modul Perl setidaknya sedikit lebih sulit daripada saya. Dan, sekali lagi, ini sudah ada di komputer saya - dan saya bahkan tidak pernah menggunakan Perl. Ada juga beberapa I18Nyang saya gulir secara salah dengan mengetahui sepenuhnya bahwa saya tidak akan membuat mereka bekerja juga.
/usr/share/i18n/locales/i18n... yang tentu saja sebagian besar berasal dari Database Karakter Unicode. Tentu saja, akan menyenangkan memiliki perintah