字符集本地化(locale)與輸入法系列講座-----(5) locale 詳解

關於locale的設定,爲什麼要設定locale 關於locale的設定 

locale 是國際化與本土化過程中的一個非常重要的概念,個人認爲,對於中文用戶來說,通常會涉及到的國際化或者本土化,大致包含三個方面:看中文,寫中文,與 window中文系統的兼容和通信。從實際經驗上看來,locale的設定與看中文關係不大,但是與寫中文,及window分區的掛載方式有很密切的關係。本人認爲就像一個純英文的Windows能夠瀏覽中文,日文或者意大利文網頁一樣,你不需要設定locale就可以看中文。那麼,爲什麼要設定 locale呢?什麼時候會用到locale呢? 

 

一、爲什麼要設定locale 正如前面我所講的,設定locale與你能否瀏覽中文的網頁沒有直接的關係,即便你把locale設置成 en_US.ISO-8859-1這樣一個標準的英文locale你照樣可以瀏覽中文的網頁,只要你的系統裏面有相應的字符集(這個都不一定需要:如果你就用unicode 來直接存儲符號,就不需要字符集)和合適的字體(如simsun),瀏覽器就可以把網頁翻譯成中文給你看。具體的過程是網絡把網頁傳送到你的機器上之後,瀏覽器會判斷相應的編碼的字符集,根據網頁採用的字符集,變成統一的unicode內碼(字符集對應的unicode內碼文件,如:ubuntu 在/usr/share/i18n/charmaps),再根據你程序所設置的字體去字體庫(字體庫文件,如:ubuntu字體在:/usr/share/fonts)裏面找與這個unicode內碼相對應的字體,根據瀏覽器程序給出的字體大小,顏色等等與計算機屏幕的信息,然後由文字渲染工具(如:freetype)根據算法把相應的算出合適這個屏幕的字體 把相應的文字在屏幕上顯示出來。

那有時候網頁顯示亂碼或者都是方框是怎麼回事呢?個人認爲,顯示亂碼是因爲設定的字符集不對(或者沒有相應的字符集),例如網頁是用UTF-8編碼的,你非要用GB2312去看,而系統根據GB2312去找字體,然後在屏幕上顯示,當然是一堆的亂碼,也就是說你用一個錯誤的字符集去翻譯發給你的電報,當然內容那叫一個亂;至於有些時候瀏覽的網頁能顯示一部分漢字,但有很多的地方是方框,能夠顯示漢字說明瀏覽器已經正確的判斷出了網頁的編碼,並在字體庫裏面找到了相應的文字,但是並不是每個字體庫都包含某個字符集全部的字體的緣故,有些時候會顯示不完全,找一個比較全的支持較多字符集的字體就可以了。 

 

二 既然我能夠瀏覽中文網頁,那爲什麼我還要設定locale呢? 

其實你有沒有想過這麼一個問題,爲什麼gentoo官方論壇上中文論壇的網頁是用UTF-8編碼的(雖然大家一直強烈建議用GB2312編碼),但是新浪網就是用GB2312編碼的呢?而Xorg的官方網頁竟然是ISO-8859-15編碼的,我沒有設定這個locale怎麼一樣的能瀏覽呢?這是因爲你有所有的字符集,不論某個網站是用什麼字符集編碼的,你都可以用你手裏的字符集把他們翻譯過來,但問題是雖然你能瀏覽中文網頁,但當寫的時候你不能每寫一個字,就叫程序選擇字符集,這樣就要事先規定個字符集,這完全是爲了符合人的方便乾的事.

三、什麼是字符集? 字符集就是字符,尤其是非英語字符在系統內的編碼方式,也就是通常所說的內碼,所有的字符集都放在 /usr/share/i18n/charmaps,所有的字符集也都是用Unicode編號索引的。Unicode用統一的編號來索引目前已知的全部的符號。而字符集則是這些符號的編碼方式,或者說是在網絡傳輸,計算機內部通信的時候,對於不同字符的表達方式,Unicode是一個靜態的概念,字符集是一個動態的概念,是每一個字符傳遞或傳輸的具體形式。就像 Unicode編號U59D0是代表姐姐的“姐”字,但是具體的這個字是用兩個字節表示,三個字節,還是四個字節表示,是字符集的問題。例如:UTF-8字符集就是目前流行的對字符的編碼方式,UTF-8用一個字節表示常用的拉丁字母,用兩個字節表示常用的符號,包括常用的中文字符,用三個表示不常用的字符,用四個字節表示其他的古靈精怪的字符。而GB2312字符集就是用兩個字節表示所有的字符。需要提到一點的是Unicode除了用編號索引全部字符以外,本身是用四個字節存儲全部字符,這一點在談到掛載windows分區的時候是非常重要的一個概念。所以說你也可以把Unicode看作是一種字符集但是這樣表述符號是非常浪費資源的,因爲在計算機世界絕大部分時候用到的是一個字節就可以搞定的 26個字母而已。所以纔會有UTF-8,UTF-16等等,要不然大同世界多好,省了這許多麻煩。

 

四、zh_CN.GB2312到底是在說什麼? Locale 是軟件在運行時的語言環境, 它包括語言(Language), 地域  (Territory) 和字符集(Codeset)。一個locale的書寫格式爲: 語言[_地域[.字符集]]. 所以說呢,locale總是和一定的字符集相聯繫的。下面舉幾個例子: 

1、我說中文,身處中華人民共和國,使用國標2312字符集來表達字符。 zh_CN.GB2312=中文_中華人民共和國+國標2312字符集。 

2、我說中文,身處中華人民共和國,使用國標18030字符集來表達字符。 zh_CN.GB18030=中文_中華人民共和國+國標18030字符集。 

3、我說中文,身處中華人民共和國臺灣省,使用國標Big5字符集來表達字符。 zh_TW.BIG5=中文_臺灣.大五碼字符集 

4、我說英文,身處大不列顛,使用ISO-8859-1字符集來表達字符。 en_GB.ISO-8859-1=英文_大不列顛.ISO-8859-1字符集 

5、我說德語,身處德國,使用UTF-8字符集,習慣了歐洲風格。 de_DE.UTF-8@euro=德語_德國.UTF-8字符集@按照歐洲習慣加以修正 

注意不是[email][email protected][/email]-8,所以完全的locale表達方式是 [語言[_地域][.字符集] [@修正值] 

生成的locale放在/usr/lib/locale/目錄中,並且每個locale都對應一個文件夾,也就是說創建了[email] [email protected][/email]-8 locale之後,就生成/usr/lib/locale/[email protected]/目錄,裏面是具體的每個locale的內容。

 

五、locale的五臟六腑 

剛剛生成了幾個locale,但是爲了讓它們生效,必須告訴Linux系統使用那(幾)個locale。這就需要對locale的內部機制有一點點的瞭解。在前面我已經提到過,locale把按照所涉及到的文化傳統的各個方面分成12個大類,這12個大類分別是: 1、語言符號及其分類 (LC_CTYPE) 2、數字(LC_NUMERIC) 3、比較和排序習慣(LC_COLLATE) 4、時間顯示格式(LC_TIME) 5、貨幣單位(LC_MONETARY) 6、信息主要是提示信息,錯誤信息, 狀態信息, 標題, 標籤, 按鈕和菜單等(LC_MESSAGES) 7、姓名書寫方式(LC_NAME) 8、地址書寫方式(LC_ADDRESS) 9、電話號碼書寫方式(LC_TELEPHONE) 10、度量衡表達方式 (LC_MEASUREMENT) 11、默認紙張尺寸大小(LC_PAPER) 12、對locale自身包含信息的概述 (LC_IDENTIFICATION)。 

其中,與中文輸入關係最密切的就是 LC_CTYPE, LC_CTYPE 規定了系統內有效的字符以及這些字符的分類,諸如什麼是大寫字母,小寫字母,大小寫轉換,標點符號、可打印字符和其他的字符屬性等方面。而locale定義zh_CN中最最重要的一項就是定義了漢字(Class  “hanzi”)這一個大類,當然也是用Unicode描述的,這就讓中文字符在Linux系統中成爲合法的有效字符,而且不論它們是用什麼字符集編碼的。 

LC_CTYPE % This is a copy of the "i18n" LC_CTYPE with the following modifications: - Additional classes: hanzi 

copy "i18n" 

class "hanzi"; / % ..;/ ..;/ ;;;;;;;;/ ;;;;;;;;/ ;;;; END LC_CTYPE 

在en_US的locale定義中,並沒有定義漢字,所以漢字不是有效字符。所以如果要輸入中文必須使用支持中文的locale,也就是zh_XX,如zh_CN,zh_TW,zh_HK等等。 

另外非常重要的一點就是這些分類是彼此獨立的,也就是說LC_CTYPE,LC_COLLATE和 LC_MESSAGES等等分類彼此之間是獨立的,可以根據用戶的需要設定成不同的值。這一點對很多用戶是有利的,甚至是必須的。例如,我就需要一個能夠輸入中文的英文環境,所以我可以把 LC_CTYPE設定成zh_CN.GB18030,而其他所有的項都是en_US.UTF-8。 

六、怎樣設定locale呢? 

設定locale就是設定12大類的locale分類屬性,即 12個LC_*。除了這12個變量可以設定以外,爲了簡便起見,還有兩個變量: LC_ALL和LANG。它們之間有一個優先級的關係: LC_ALL>LC_*>LANG 可以這麼說,LC_ALL是最上級設定或者強制設定,而LANG是默認設定值。 1、如果你設定了LC_ALL=zh_CN.UTF-8,那麼不管LC_*和LANG設定成什麼值,它們都會被強制服從 LC_ALL的設定,成爲 zh_CN.UTF-8。 2、假如你設定了LANG=zh_CN.UTF-8,而其他的LC_*=en_US.UTF-8,並且沒有設定LC_ALL的話,那麼系統的locale設定以LC_*=en_US.UTF-8。 3、假如你設定了LANG=zh_CN.UTF-8,而其他的LC_*,和LC_ALL均未設定的話,系統會將LC_*設定成默認值,也就是LANG的值 zh_CN.UTF-8 。 4、假如你設定了 LANG=zh_CN.UTF-8,而其他的LC_CTYPE=en_US.UTF-8,其他的LC_*,和LC_ALL均未設定的話,那麼系統的 locale設定將是:LC_CTYPE=en_US.UTF-8,其餘的 LC_COLLATE,LC_MESSAGES等等均會採用默認值,也就是 LANG的值,也就是LC_COLLATE=LC_MESSAGES=……= LC_PAPER=LANG=zh_CN.UTF-8。 

所以,locale是這樣設定的: 1、如果你需要一個純中文的系統的話,設定LC_ALL= zh_CN.XXXX,或者LANG=  zh_CN.XXXX都可以,當然你可以兩個都設定,但正如上面所講,LC_ALL的值將覆蓋所有其他的locale設定,不要作無用功。 2、如果你只想要一個可以輸入中文的環境,而保持菜單、標題,系統信息等等爲英文界面,那麼只需要設定LC_CTYPE=zh_CN.XXXX,LANG=  en_US.XXXX就可以了。這樣LC_CTYPE=zh_CN.XXXX,而LC_COLLATE=LC_MESSAGES=……=  LC_PAPER=LANG=en_US.XXXX。 3、假如你高興的話,可以把12個LC_*一一設定成你需要的值,打造一個古靈精怪的系統:  LC_CTYPE=zh_CN.GBK/GBK(使用中文編碼內碼GBK字符集); LC_NUMERIC=en_GB.ISO-8859-1(使用大不列顛的數字系統) [email protected](德國的度量衡使用ISO-8859-15字符集) 羅馬的地址書寫方式,美國的紙張設定……。估計沒人這麼幹吧。 4、假如你什麼也不做的話,也就是LC_ALL,LANG和LC_*均不指定特定值的話,系統將採用POSIX作爲lcoale,也就是C locale。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章