漢字字符編碼的科普筆記(GB2312漢字編碼,Unicode與UTF-8,字符映射表,vim,文泉驛,正則表達式)

折騰了兩天的結果 來源: 田野wafield的日誌

GB2312cp936

1. GB2312簡介

GB2312GB2312-80,誕生於1981年,共收錄6763個漢字,其中一級漢字3755個,二級漢字3008個;同時收錄了包括拉丁字母、希臘字母、日文平假名及片假名字母、俄語西裏爾字母在內的682個字符,共7445個字符。GB2312的出現,基本滿足了漢字的計算機處理需要,它所收錄的漢字已經覆蓋中國大陸99.75%的使用頻率。用區位碼錶示。範圍:區(01-87),位(01-94)。

2. Code Page

Windows中使用VIM打開一個以GB2312方式編碼的文檔時,file encoding顯示的是“cp936”。在Windows中,code page指的就是字符集,在其他操作系統中稱爲字符編碼(character encodings),兩者是同一概念。code pages8090年代的Windows操作系統中使用,當Windows實現了Unicode時,code pages就逐漸被取代。Code Page這個詞來源於IBM的基於EBCDICmainframe系統,但包括微軟、SAPOracle在內的很多製造商都使用這個說法。

另一個很奇怪的事情是,同樣一份以GB2312編碼的文檔,在Windows裏用VIM打開,就顯示爲cp936編碼;在Linux裏打開時卻顯示爲utf-8編碼,而不是“cp936”的unix說法“euc-cn”!但是以十六進制方式查看,發現文字確實是以GB2312編碼的。可能是vimrc裏不知道哪兒寫錯了。具體情況請見VIM的幫助文檔“:h encoding-values”。

3. GB2312的編碼

每個漢字及符號以兩個字節來表示,高位字節使用了0xA1-0xF7;低位字節使用了0xA1-0xFE 由於一級漢字從16區起始,漢字區的“高位字節”的範圍是0xB0-0xF7,“低位字節”的範圍是0xA1-0xFE

Unicode出現後,GB2312的全部7445個字符都在Unicode的覆蓋範圍之內,並分佈在U+00A4U+FFE5之間。另外,GB2312的常用漢字按拼音排列,次常用漢字按筆畫排列,因此與Unicode的漢字部分的字序是不同的。

GBKChinese Internal Code Specification

1. 簡介

GBK誕生於1993年的Unicode 1.1版之後。之前的GB2312-80只有6763個漢字,且很多漢字在1981年之後纔得到簡化,故中國大陸制定了等同於Unicode 1.1版的“GB 13000.1-93”,收錄中國大陸、臺灣、日本、韓國的通用字符集,共20902個漢字。微軟利用GB 2312-80未使用的編碼空間,收錄GB 13000.1-93全部字符制定了GBK編碼。最早實現於Windows 95簡體中文版。雖然GBK收錄GB 13000.1-93的全部字符,但編碼方式並不相同。以下爲GBK的雙字節編碼示意:

2. 編碼

字符有一字節和雙字節編碼,00-7F範圍內是一位,和ASCII保持一致,此範圍內嚴格上說有96個文字和32個控制符號。雙字節中,第一字節的範圍是81-FE(也就是不含80FF),第二字節的一部分領域在40-FE,其他領域在80-FE

GB18030

1. 簡介

最新版本爲GB 18030-2005,與GB 2312-1980完全兼容,與GBK基本兼容,支持GB 13000Unicode的全部統一漢字,共收錄漢字70244個。與UTF-8 相同,採用多字節編碼,每個字可以由1個、2個或4個字節組成。支持中國國內少數民族的文字,收錄範圍包含繁體漢字以及日韓漢字。

2. 編碼

單字節部分,收錄了GB/T 11383-19890x000x7F全部128個字符;雙字節部分:GB 13000.1-1993的全部CJK統一漢字字符等,其首字節碼位從0x810xFE,尾字節碼位分別是0x400x7E0x800xFE。;四字節部分:收錄了上述雙字節字符之外的,GB 13000CJK統一漢字擴充ACJK統一漢字擴充B和已經在GB 13000中編碼的中國少數民族文字的字符,採用0x300x39作爲對雙字節編碼的擴充的後綴。這樣擴充的四字節編碼,其範圍爲0x813081300xFE39FE39。四字節字符的第一個字節的編碼爲0x810xFE;第二個字節的編碼範圍爲0x300x39;第三個字節編碼範圍爲0x810xFE;第四個字節編碼範圍爲0x300x39

Unicode

1. Unicode中的scripts

Unicode中的script指的是一種或多種書寫系統中,用來代表文字信息的一個字符或其他書寫符號的集合。例如,俄語和烏克蘭語分別是西里爾script的不同子集。有些script支持且僅支持一種書寫系統和語言,如亞美尼亞script;另一些scripts支持多種不同的書寫系統,如Latin script支持英語、法語、德語、意大利語、越南語和拉丁語。有些語言使用多種不同的書寫系統,因此也使用若干個scripts。在土耳其語中,阿拉伯語的script20世紀之前使用,但到20世紀早期則轉變爲Latin script。漢字書寫系統使用在以下語言中:普通話、吳語、粵語、閩語(譯者注:臺語)、湘語、客家語、贛語、晉語、徽州語、廣西平語、侗語、白語(已廢棄)、苗語(已廢棄)、壯語(已廢棄)、日語、韓語(已廢棄,只使用於學術文本和報紙中),越南語(用於歷史文獻、學術文獻或出於藝術與審美的考慮)及其他已經失傳的語言(契丹文、女真文、西夏文)。

scripts相補充的是Unicode symbolsScriptssymbols覆蓋了所有的Unicode字符,統一發音符號和統一標點符號字符經常具有內在的script屬性,但是單獨的script常常也具有自己的發音符號和標點符號。所以很多script不僅包括字母,也包括髮音符號和其他標記、標點符號、數字甚至其自己的特異性的符號和空白字符。

下圖分別爲以Script爲單位和以區塊爲單位劃分Unicode字符。

關於CJK統一表意文字(Han ideographic characters):Unicode標準中的“統一表意文字”的說法是西文中一個傳統詞語,儘管專業語言學家更喜歡“Sinogram”這個詞。字面上說,ideograph只適用於某些古代的、原始的漢字形式,這些字的確是來源於表意描述。但絕大部分漢字是後來經組合、假借和其他非表意性的原則發展而來的,但“Han ideographs”這個說法仍在英文中沿用。

2. Unicode平面(Plane

Unicode將代碼點(Code Point)分爲17個平面,其中第0個平面(基礎多語言平面,Base Multilingual Plane)包含代碼點0x0000-0xFFFF,第1個平面包含0x10000-0x1FFFF,以此類推。其實第0平面已經包含了絕大部分各種語言的常用字符,位置空間分佈示意圖如下(左上角爲原點,格子中的兩位十六進制數表示高位字節):

包含漢字(Han ideographs)的區塊有:

  • CJK統一表意文字(4E00-9FFF):常用漢字
  • CJK統一表意文字擴展A3400-4DBF):罕用漢字
  • CJK統一表意文字擴展B20000-2A6DF):罕用漢字
  • CJK統一表意文字擴展C2A700-2B73F):罕用漢字
  • CJK兼容表意文字(F900-FAFF):重複字符,可統一的異形字
  • CJK兼容表意文字補充(2F800-2FA1F):可統一的異形字

UTF-8

1. 簡介

全稱UCS Transformation Format – 8-bit,是一種對Unicode的多字節編碼。與UTF-16UTF-32類似,UTF-8可以表示Unicode字符集中的每個字符。與它們不同的是,UTF-8ASCII是向後兼容的,並且避免了尾數(endianness)的複雜性。鑑於各種原因,UTF-8已成爲www最重要的字符編碼,涉及超過半數網頁。UTF-8使用14個字節對Unicode字符集中的1,112,064個代碼點中的每一個進行編碼。具體而言,使用1-3個不等的字節數編碼Unicode的第0個平面。數值較低的代碼點使用較少的字節數,使得編碼體系較爲高效。注意,Unicode對所有字符進行編碼,完成從字符到代碼點(如0x4E00)的映射,而與字符的具體表示無關;UTF-8完成由編碼到內在表示(字節碼)的映射,而不關心某個編碼具體代表哪個字符。

2. 編碼範圍

Unicode字符集的前128個字符與ASCII碼保持一對一關係,使用一個字節進行編碼,使得有效的ASCII文本在UTF-8編碼的Unicode下仍然有效。理論上,UTF-8可以至多編碼231次方字符(即Universal字符集起草時的理論上限)。

3. 編碼規則

如果一個字符用一個字節編碼,則最高位是0,其他位給出編碼值(0127);

如果一個字符用kk>=2字節編碼,則第一個字節的前k位爲1,接着是一個0。隨後的(k-1字節全部由“10”開頭。所有字節的剩餘位連接起來,形成了Unicode代碼點值,從0x800x10FFFF。由此可見:

1)一個以0開頭的字節表示單字節字符

2)一個以11開頭的字節表示一個多字節字符的開頭

3)一個以10開頭的字節表示一個多字節字符的非開頭

這樣設計使得任何一個字節序列都可以被識別,並不需要從字符串的頭部開始。另外由圖可見,UTF-8其實是使用1-6個字節來代表一個字符的,即可以表示到0x7FFFFFFF,但是據說爲了與UTF-16兼容,最高的若干位沒有用,只用到0x10FFFF

以下面這個文檔爲例,文檔以UTF-8編碼。

使用16進制方式顯示,如圖:

分析如下:

1)在UTF-8中,單個字母是用一個字節表示的,如A表示爲0x41(十進制的65),以此可以定位到漢字“一”被表示爲三個字節:0xe4, 0xb8, 0x80

2)漢字“一”是UnicodeCJK統一表意文字區的第一個字符,Unicode碼爲0x4e00,既然表示爲三個字節,則使用“1110xxxx 10xxxxxx 10xxxxxx”的模板,把4e00這十六位編碼套進去,正好就是“e4 b8 80”;

3fileformatunix,因此換行符是一個<NL>,即0x0a

4)上述文檔在Ubuntu裏說大小爲29 bytes,數一數的確如此。

六 文泉

1. 簡介

作爲幾千年中華文明的見證,浩瀚傳統文化傳承的載體,漢字是讓我們每一箇中國人引以爲豪的東方文明標誌之一。我們的祖先創造漢字,書寫漢字,利用漢字和漢語的無窮魅力創造出讓人歎爲觀止的文學、藝術。而今天進入了計算機時代的我們,雖然不再古人一樣手持毛筆,批著簡帛,但我們的生活仍然無時無刻離不開漢字。

可以毫不誇張的講,漢字是世界上已知的最爲龐大的符號系統。早在殷商時期,我們的先人就創造出了數目巨大的甲骨文,從上萬片發掘的甲骨中整理出來的單字就有四千餘個。東漢許慎編撰的“說文解字”,收錄漢字 9,353個。至清朝康熙年間,由段玉裁等人收集整理的“康熙字典”收錄漢字竟達 47,035 之多。加上少數民族文字,各種古代典籍上曾經出現但並未廣泛使用的古漢字和異體字,漢字總數多達十萬以上。作爲現代計算機系統通用編碼的統一碼(Unicode)在最新發布的5.2版中共收錄漢字(包括簡體、繁體,以及日、韓、越等地區使用的漢字) 74,394 。(注:微軟的中易宋體的最新版本只有42,809個字)

我們是一羣致力於在計算機世界中推廣漢字,豐富電子漢字資源的志願者。我們希望通過自己無私的勞動,使得無論您在世界上任何一個角落,都可以免費地獲得我們的電子漢字資源,能夠流暢地通過漢字進行交流。“文泉驛”是以上述目標爲宗旨而自發創建的非盈利性組織。

2. 文泉正黑(WenQuanYi Zen Hei

文泉正黑體是一個"自由字體"。該字體包含了所有常用簡體中文、繁體中文所需要的漢字(最新版本包含超過27842個漢字,完整覆蓋GB2312/Big5/GBK以及GB18030標準字符集)。該字體同時還包含了日文、韓文和其他幾十種語言符號。除此以外,該字體還嵌入了最新版本的文泉點陣宋體的中英文點陣,使得屏幕漢字顯示清晰銳利,易於閱讀。

作爲黑體中文字體,文泉正黑爲非襯線字體,筆畫對比度明顯,特別適合屏幕漢字顯示以及文檔標題字體。

3. 文泉微米黑(WenQuanYi Micro Hei

文泉微米黑是一個"自由字體"。該字體包含了所有常用簡體中文、繁體中文所需要的漢字(最新版本包含超過20932個漢字,完整覆蓋GB2312/Big5以及GBK標準字符集)。該字體同時還包含了日文、韓文和其他幾十種語言符號。以外,該字體還包含了高質量的Droid Sans拉丁符號和Droid Sans Mono等寬字體,並內置HintingKerning信息。微米黑字體文件極小,特別使用於便攜式電腦設備。

4. 文泉點陣宋體(WenQuanYi Bitmap Song

文泉點陣宋體是一個"自由中文字體"。該字體包含了所有常用簡體中文、繁體中文,日文及韓文所需要的漢字(最新版本包含超過27842個漢字,完整覆蓋GB2312/Big5/GBK/GB18030標準字符集)。該字體同時還包含了英文、日文、韓文和其他多種語言符號。該點陣字體包含五個屏幕常用字號(9pt-12pt),逾21萬漢字點陣,這些點陣都經過參與者和組織者的精心設計和調整,手工優化後的漢字點陣顯示清晰銳利,特別易於屏幕閱讀使用。

我們目前提供下載的文泉點陣宋體只能夠在Linux/Unix系統上使用。在Windows上使用該字體,請下載文泉正黑體,正黑體嵌入了所有GBK漢字點陣,在9-12pt範圍內,將自動使用點陣宋體顯示。

七 正則表達式

1. Unicode字符的一般正則表達式表示

支持Unicode的程序中的正則表達式通常支持\uNUM原序列,用來匹配一個具體的Unicode字符。這個數值通常是一個4位十六進制數,例如,\uC0B5的意思是“匹配編號爲U+C0B5Unicode字符”,而沒說具體需要比較哪些字節,因爲具體的字節是由代表這個Unicode代碼點的編碼方式在內部決定的。如果程序內部使用的是UTF-8編碼,這個字符就用3個字符表示。不過使用支持Unicode程序的用戶,並不需要關心這個。

爲了匹配任何一個Unicode字符,應該用\X,這相當於Unicode中的點號。在Java中,用\uFFFFFFFF是代碼點)來匹配某個特定的Unicode字符。

2. PerlPCREUnicode字符的正則表達式表示

PerlPCRE中,並不支持\uFFFF這樣的語法,而是使用\x{FFFF}。例如,\x{1234}不會和“匹配\x 1234次”混淆,而是永遠代表U+1234這個Unicode字符;\x{1234}{5678}則代表匹配U+1234這個Unicode字符整整5678次。

PerlPCRE還是極少數的支持基於ScriptsUnicode進行匹配的正則表達式引擎!方法是\p{Script_Name}例如,\p{Bopomofo}匹配一個注音符號字母,\p{Han}匹配一個漢字。此外還支持基於區塊的匹配,如\p{InCJK_Unified_Ideographs}匹配所有CJK統一表意文字區的字符(等同於U+4E00…U+9FFF

Perl中讀取以UTF-8編碼的文件,還有另一個問題:當使用<><FILEHANDLE>等方式讀取文件時,perl會把文件視爲一系列字節流,而UTF-8是變長字節編碼的,想以字符(而不是字節)爲單位來處理,則必須進行解碼。

例如,運行如下代碼

打印出來的是每行一個帶問號的小菱形,說明字符串$_中每個單元是一個字節。要解決這個問題,有兩種思路:一方面使用binmode改造句柄,使之以UTF-8方式讀取,如下:

但是這樣有個問題是第一個字符不能正常讀取!之後的都正常!這是爲什麼啊!另一個思路是對讀入的字符串進行處理,即告訴perl這個字符串(本質上是字節序列)要以UTF-8的多字節方式解析。這一過程是decode,因此用以下方法可以解決問題:

讀入之後,就可以用\x{abcd}, \p{Han}\p{InCJK_Unified_Ideographs}等方式對其進行正則表達式處理了。

3. VimUnicode正則表達式的支持

         作爲最強大的文本編輯器,Vim對正則表達式的支持是人盡皆知的。而且,畢竟是文本編輯器,執行個查找啊替換啊這種處理會比用perl直觀得多。但是,對於Unicode字符的支持,Vim採用的正則表達式引擎卻遠比不上Perl(圖爲節選)

有人說,爲什麼Vim不用PCRE呢?回覆說,ViPerl出來的早得多,應該問爲什麼Perl不跟Vi學。無論如何,在Vim裏匹配Unicode字符會遇到一點麻煩:你可以用/\u4e00匹配“一”,也可以用/[\u4e00-\u4eff]匹配Unicode表中的第一行漢字(一、丁、萬、三、上……),卻不能用/[\u4e00-\u9fff]匹配CJK統一表意文字區塊中的所有文字!不知道是不是我的使用有問題!

Ubuntu中的字符映射表(Character Map

        

這是Ubuntu中相當於Windows“字符映射表”的軟件,可以在Applications -> Accessories中找到。且不說以文泉微米黑顯示的字符表有多好看,就說這個Character Details就做得非常帥,給出的信息包括:UTF-8編碼方式、XML實體表示形式、英文釋義、普通話發音、廣東話發音、日語發音、韓語發音!

工作過程中有時候需要看看UnicodeScripts,或者查找某個字符的Unicode碼,或者要copy某種北歐語言的奇怪字符,都可以用Character Map

       

另外,字符映射表支持根據字符查找與根據Unicode值查找:

在這兩天的折騰過程中,幫了不少忙。

本來只是想解決Perl處理UTF-8中文文檔的問題,不小心扯出來這麼多東西。以上是這兩天折騰的全部結果,折騰了24小時……沒有苦勞也有疲勞啊。

九 參考資料

  • http://en.wikipedia.org/wiki/Windows_code_page
  • http://en.wikipedia.org/wiki/UTF-8
  • http://en.wikipedia.org/wiki/Plane_(Unicode)
  • http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters
  • http://en.wikipedia.org/wiki/List_of_languages_by_writing_system
  • http://en.wikipedia.org/wiki/Comparison_of_regular_expression_engines
  • http://en.wikipedia.org/wiki/Code_pages
  • http://en.wikipedia.org/wiki/CJK_Unified_Ideographs
  • http://en.wikipedia.org/wiki/Basic_Multilingual_Plane
  • http://zh.wikipedia.org/wiki/Gb2312
  • http://zh.wikipedia.org/wiki/GBK
  • http://zh.wikipedia.org/wiki/GB18030
  • http://www.utf8.com/
  • http://www.unicode.org/versions/Unicode5.2.0
  • http://www.unicode.org/reports/tr18/
  • http://www.unicode.org/charts/
  • http://www.regular-expressions.info/charclass.html
  • http://wenq.org/index.cgi?ZenHei
  • http://wenq.org/index.cgi?MicroHei
  • http://wenq.org/?BitmapSong
  • http://vim.wikia.com/wiki/Perl_compatible_regular_expressions
  • http://perldoc.perl.org/perlunicode.html
  • http://msdn.microsoft.com/en-us/library/20bw873z.aspx
  • http://forum.ubuntu.org.cn/viewtopic.php?t=244756

源地址:http://blog.renren.com/GetEntry.do?id=768109271&owner=231526558

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