在 UNIX 的世界中,形成了「程序國際化」與「數(shù)據(jù)本土化」的標(biāo)準(zhǔn),程序代碼只要寫過一遍,就可以適用于所有的語文與編碼系統(tǒng),只要系統(tǒng)有支持該語文與編碼系統(tǒng)所需的「本土數(shù)據(jù)」即可。即采取的概念就是「程序」與「數(shù)據(jù)」分離并分開維護(hù)的方式。
「程序國際化」簡稱 I18N,其意為 InternationalizatioN 一字中頭尾字母 "I" 與"N" 中間夾 18 個(gè)英文字母,故名。它是在系統(tǒng)底層的函式庫 (即 libc 函式庫) 中實(shí)作一組標(biāo)準(zhǔn)的函式接口,可以讓程序存取該地區(qū)語系的種種信息。有了這些信息,程序本身不僅可以不需要修改,就足以處理各國的語文,同時(shí)程序本身甚至連各地區(qū)語文的各項(xiàng)細(xì)節(jié) (如編碼方式 .... 等) 都不需要知道,因?yàn)檫@些全部都是由系統(tǒng)函式庫提供的。
「資料本土化」簡稱 L10N,其意為 LocalizatioN 一字中頭尾字母 "L" 與 "N" 中間夾 10 個(gè)英文字母,故名。它是將地區(qū)語文的各項(xiàng)細(xì)節(jié)數(shù)據(jù)分門別類,安裝在系統(tǒng)底層的數(shù)據(jù)庫中,以便讓系統(tǒng)函式庫存取,以提供給上頭的應(yīng)用程序使用。這些用來描述各地區(qū)語文的數(shù)據(jù),我們稱之為「地區(qū)環(huán)境數(shù)據(jù)庫 (locale)」,或簡稱「地區(qū)環(huán)境」它們包括以下的類別 (categories):
1. LC_COLLATE: 該地區(qū)文字排序規(guī)則,以及正規(guī)化表示式 (regular expression)的比對依據(jù)。
2. LC_CTYPE: 該地區(qū)所使用的編碼系統(tǒng)、字集、與文字分類、轉(zhuǎn)換等信息。
3. LC_MESSAGES: 各應(yīng)用程序區(qū)域化的訊息顯示。
4. LC_MONETARY: 該地區(qū)所通行的貨幣格式。
5. LC_NUMERIC: 該地區(qū)所通行的數(shù)字表示格式。
6. LC_TIME: 該地區(qū)所通行的時(shí)間、日期表示格式。
· 對于同一個(gè)地區(qū)語文而言,除了 LC_MESSAGES 之外,其它所有的類別都是固定的,故這些類別的數(shù)據(jù)就只需準(zhǔn)備一份即可,它們是由系統(tǒng)底層函式庫直接提供,可以讓所有的應(yīng)用程序分享。至于 LC_MESSAGES 訊息顯示的部分,由于各應(yīng)用程序的訊息都不同,故這部分的數(shù)據(jù)是由應(yīng)用程序自身提供,而不像其它類別一樣由系統(tǒng)函式庫提供。
·在這些類別中,決定一個(gè)程序是否在該地區(qū)已「本土」化的最重要因素,一是 LC_CTYPE,二是 LC_MESSAGES。前者賦與程序處理該地區(qū)文字的能力,后者賦與程序用該地區(qū)的語文來顯示的能力。
· 在實(shí)際中,將程序所有的訊息集中放在一個(gè)文件檔中,而該文件文件的訊息開始時(shí)只會(huì)用程序原作者慣用的語言來表示。如果希望該程序也能顯示其它語文的訊息時(shí),我們只需要去做翻譯的工作即可,而不必真的去修改程序代碼本身。因此,訊息翻譯與程序維護(hù)可以分頭進(jìn)行,翻譯的工作不需要由程序原作者、或有經(jīng)驗(yàn)的程式設(shè)計(jì)師來做,只需他熟悉該語文,并對該程序有一定的熟悉度即可。故基本上,任何人都可以參與翻譯的工作。當(dāng)程序編譯安裝完成后,已翻譯成各國語文的訊息文件也會(huì)一并安裝入系統(tǒng)的區(qū)域化數(shù)據(jù)庫中。當(dāng)程序啟動(dòng),需要做訊息顯示時(shí),它會(huì)呼叫系統(tǒng)提供的函式介面,依目前的語系設(shè)定來正確抓取該語文的訊息并顯示出來。萬一目前的語系設(shè)定找不到相對應(yīng)的訊息翻譯文件時(shí),則程序會(huì)自動(dòng)以其原始的語系來顯示。
地區(qū)環(huán)境數(shù)據(jù)庫名稱和語系設(shè)定
各地區(qū)所屬的地區(qū)環(huán)境數(shù)據(jù)庫名稱格式如下:
_[.]
其中 [.] 有時(shí)候會(huì)省略。以我們臺(tái)灣地區(qū)所使用的為例:
zh_CN.UTF-8其意即為「中文語系」(zh)「中國」(CN)「使用UTF-8編碼系統(tǒng)」。如果將后頭的 [.] 省略掉,就是這個(gè)樣子
zh_CN
·如果我們不特別做語系的設(shè)定,則程序在啟動(dòng)時(shí),會(huì)以系統(tǒng)預(yù)設(shè)的語系來運(yùn)作,一般而言其地區(qū)環(huán)境數(shù)據(jù)庫名就是 "C" 或 "POSIX",也就是原始 C 語言所采用的編碼系統(tǒng) (ASCII) 與英文訊息等等。如果希望改變程序運(yùn)作的語系,則我們必須在程序啟動(dòng)前先做好環(huán)境語系的設(shè)定,也就是設(shè)好各類別的環(huán)境變量。例如:
LC_CTYPE=zh_CN.UTF-8; export LC_CTYPE
LC_MESSAGES=zh_CN.UTF-8; export LC_MESSAGES
·假如希望程序可以處理 EUC-TW 的文字,但仍以 Big5 中文顯示訊息時(shí),就這樣設(shè)定:
LC_CTYPE=zh_TW.euctw; export LC_CTYPE
LC_MESSAGES=zh_TW.Big5; export LC_MESSAGES
· 在多數(shù)情況下,通常會(huì)希望一口氣將所有的類別設(shè)定成相同的語系,也就是讓我們的整體環(huán)境全部處于同一個(gè)語系下。當(dāng)然我們可以用上述的方式一個(gè)個(gè)類別分別設(shè)定,但除此之外系統(tǒng)還提供了另外兩個(gè)環(huán)境變量,以方便我們的作業(yè)。一是 LANG,另一個(gè)是 LC_ALL。例如我們這樣設(shè):
LC_ALL=zh_CN.UTF-8; export LC_ALL
其效果就完全等價(jià)于將所有的類別全部設(shè)定了。而 LANG 的用法也是一樣,所達(dá)到的效果也類似,但意義稍有不同,這里要留意優(yōu)先級(jí)的差別。一般系統(tǒng)對這些環(huán)境變數(shù)的優(yōu)先級(jí)是:LC_ALL > LC_* > LANG
·也就是說,任何一個(gè) LC_ 類的變量設(shè)定后,會(huì)使 LANG 的設(shè)定的相對應(yīng)類別失效。如果我們完全不設(shè)任何的 LC_ 類的環(huán)境變量,只單單這么設(shè)
LANG=zh_CN.UTF-8; export LANG
則所有的類別都會(huì)以 LANG 的設(shè)定來運(yùn)作,除非我們特別去設(shè)了某個(gè) LC_ 的環(huán)境變數(shù),如此這個(gè)類別就會(huì)以新的設(shè)定來運(yùn)作 (但其它的類別不變)。相似的道理,如果我們設(shè)了 LC_ALL 的環(huán)境變量,則所有的類別設(shè)定,包括 LANG 的設(shè)定全部會(huì)失效,而改以 LC_ALL 的設(shè)定來運(yùn)作。