首頁  >  文章  >  後端開發  >  詳解Unicode和Python的中文處理方法

詳解Unicode和Python的中文處理方法

高洛峰
高洛峰原創
2017-03-20 09:06:561393瀏覽

Python語言中,Uincode字串處理一直是個容易讓人迷惑的問題。許多Python愛好者經常因為搞不清Unicode、UTF-8還有其它許許多多的編碼之間的區別而大傷腦筋。本文將介紹Unicode和Python的中文處理的相關知識。下面跟著小編一起來看下吧

在Python語言中,Uincode字串處理一直是個容易讓人困惑的問題。許多Python愛好者經常因為搞不清Unicode、UTF-8還有其它許許多多的編碼之間的區別而大傷腦筋。筆者曾經也是這位「傷腦筋一族」的成員,但經過半年多的努力,現在終於初步弄清楚其中的一些關係。現將其整理如下,與各位同仁同享。同時也希望能藉這篇短文拋磚引玉,吸引更多真正的高手加入進來,共同完善我們的Python中文環境。

本文所提到的各種觀點,一部分是查閱資料所得,還有一部分是筆者利用已有各種編碼資料用「猜測加驗證」法得到。筆者自問才疏學淺,其中怕是藏有不少錯誤。各位看官中不乏高手,如果有哪一位發現其中哪裡有錯,萬望各位高人不吝賜教。筆者自己丟醜事小,觀點錯誤誤了別人事大,因此各位大可不必顧忌筆者的面子問題。

第一節 文字編碼和Unicode標準

要解釋Unicode字串就必須先從什麼是Unicode編碼開始說起。眾所周知,文字顯示一直是電腦顯示功能必須解決的基本問題。而電腦並不識字,它實際上是把文字看做是一串“圖片”,每張“圖片”對應一個字元。每個電腦程式在顯示文字時,必須藉助一個記錄這個文字“圖片”如何顯示的“圖片”集合,從中找到每一個字元對應“圖片”的數據,並依樣畫葫蘆地把這個字“畫”到螢幕上。這個“圖片”就被稱為“字模”,而記錄字模顯示資料的集合就被稱為“字元集”。為方便程式查找,每個字元的字模資料在字元集中必須是有序排列的,而且每個字元都會被分配一個獨一無二的ID,這個ID就是字元的編碼。而當電腦進行字元資料處理時,總是用這個編碼來代表它所表示的那個字元。因此,一個字元集就規定了一組電腦能夠處理的字元資料。顯然,不同國家指定的字元集大小不同,對應的字元編碼也不同。

在電腦歷史上,最廣泛使用的標準化字元集當首推ASCII字元集。它實際上是美國製訂的標準,針對北美用戶開發。它使用7個二進位位元編碼,可以表示128個字元。這個字符集最後被ISO組織正式採納為國際標準,並且大量應用在各種電腦系統上。現如今,所有PC機的BIOS中都內含了ASCII字元集的字模,其深入人心可見一斑。

但是,當電腦在各國大規模普及時,ASCII編碼的局限性就暴露出來了:它的字符空間實在有限,無法容納更多的字符,可是絕大多數語言需要使用的字數目都遠不止128個。為了能正確處理本國文字,各國官方或民間紛紛開始了設計本國文字編碼集的工作,並且最終湧現出許許多多針對各個國家文字的字符編碼,如針對西歐字符的ISO-8859-1編碼,簡體中文的GB系列編碼,還有日文的SHIFT-JIS編碼等等。同時,為了確保各個新的字符集能夠兼容原本的ASCII文本,大多數字符集不約而同地都將ASCII字符作為自己前128個字符,並使其編碼與ASCII編碼一一對應。

這樣一來,各國文字的顯示問題是解決了,可是又帶來一個新的問題:亂碼。不同國家、地區使用的字元集通常沒有統一的規範進行約束,因此個別字元集編碼往往互不相容。同一個字在兩個不同的字元集中編碼一般不同;而同一個編碼在不同的字元集中對應的字元也不一樣。一段用編碼A寫的文字在一個只支援編碼B的系統上往往會被顯示成一堆亂七八糟的字元。更糟的是,不同字元集使用的編碼長度往往也不相同,那些只能處理單字節編碼的程式在遇到雙位元組甚至是多位元組編碼的文字時,往往因為不能正確處理而產生了臭名昭著的「半個字」問題。這使得本來就已經混亂不堪的局面更是亂成了一團粥。

為了一勞永逸地解決這些問題,業界許多大公司和組織聯合提出了一個標準,這就是Unicode。 Unicode其實是一種新的字元編碼體系。它對字元集中的每個字元以兩個位元組長的ID號進行編碼,從而規定出一個可容納多達65536個字元的編碼空間,並且將現今國際上各國編碼中的常用字盡數收入罄中。由於在設計編碼時有了周全的考慮,Unicode很好地解決了其它字元集在進行資料交流時的亂碼和「半個字」問題。同時,Unicode的設計者充分考慮到現今大量字模資料使用的仍是各國製訂的各種編碼這一現實,提出了「將Unicode作為內部編碼」的設計理念。也就是說,字元顯示程式依然使用原先的編碼和程式碼,而應用程式的內部邏輯使用的將是Unicode。當要進行文字顯示時,程式總是將Unicode編碼的字串轉換成原本的編碼進行顯示。這樣,大家就不必為了使用Unicode而重新設計字模資料體係了。同時,為了與各國已經訂定的編碼相區別,Unicode的設計者將Unicode稱為「寬字元編碼」(wide characters encodings),而各國製訂的編碼習慣上被稱為「多位元組編碼」(multi bypes encodings)。時至今日,Unicode系統又引進了四位元組的擴展編碼,並且逐漸與與UCS-4,也就是ISO10646編碼規範合流,希望有朝一日能夠用ISO10646系統統一全世界所有的文字編碼。

Unicode體系甫一出世便被大家寄予厚望,並被迅速接受為ISO認可的國際標準。但是,Unicode在推廣過程中卻遭到了首先是歐美用戶的反對。他們反對的理由非常簡單:歐美用戶原本使用的編碼都是單字節長的,雙字節的Unicode處理引擎無法處理原本的單字節資料;而如果要把現有的單字節文字全部轉換成Unicode,工作量就太大了。再說,如果所有的單字節編碼文字都被轉換成雙位元組的Unicode編碼,他們所有的文字資料所佔用的空間都會變成原來的兩倍,而且所有的處理程序都要重新編寫。這個開銷他們無法接受。

雖然Unicode是國際認可的標準,但是標準化組織不可能不考慮歐美用戶這個最大的電腦使用群體的要求。於是在各方磋商之下,一個Unicode的變種版本產生了,這就是UTF-8。 UTF-8是一個多位元組的編碼體系,它的編碼規則如下:

#1、UTF-8編碼分為四個區:

#一區為單字節編碼,

#編碼格式為​​:0xxxxxxx;
對應Unicode:0x0000 - 0x007f

二區為雙位元組編碼,

編碼格式為​​:110xxxxx 10xxxxxx;

對應Unicode:0x0080 - 0x07ff

三區為三位元組編碼,

編碼格式為​​:1110xxxx 10xxxxxxx 10xxxxxx

#對應Unicode:0x0800 - 0xffff

四區為四位元組編碼,

#編碼格式為​​:11110xxx 10xxxxxxx 10xxxxxx 10xxxxxx

對應Unicode:0x00010000 - 0x0001ffff

五區為五位元組編碼,

##編碼格式為​​:111110xx 10xxxxxxx 10xxxxxxx 10xxxxxxx 10xxxxxxx

xxxxxxxxxx Unicode:0x00200000 - 0x03ffffff

六區為六位元組編碼,

編碼格式為​​:111110x 10xxxxxxx 10xxxxxxx 10xxxx 10xxxxxx#10xxxxxxx

對應Unicode:0x04000000 - 0x7fffffff

#其中,一、二、三區對應Unicode的雙位元組編碼區,而四區則針對Unicode的四位元組擴充部分(依照該定義,UTF -8還有五區和六區,但筆者並未在GNU glibc庫中發現,不知為何);

2、各區依一、二、三、四、五、六順序排列,其對應位置上的字元與Unicode保持相同;

#3、不可顯示的Unicode字元編碼為0位元組,換言之,它們沒有被收入UTF-8(這是筆者從GNU C庫註釋中得到的說法,可能與實際情況不符);依照UTF-8編碼規則我們不難發現,其一區的128個編碼其實就是ASCII編碼。所以UTF-8的處理引擎可以直接處理ASCII文字。但是,UTF-8對ASCII編碼的相容是以犧牲其它編碼為代價的。例如,原本中、日、韓三國文字基本上都是雙位元組編碼,但它們在Unicode編碼中的位置對應到UTF-8中的三區,每個字元編碼要三個位元組長。換句話說,如果我們把所有現有的中、日、韓三國編碼的非ASCII字元文字資料轉換成UTF-8編碼,則其大小都會變成原來的1.5倍。

雖然筆者個人認為UTF-8的編碼方式顯得有些不夠公平,但它畢竟解決了ASCII文本到Unicode世界的過渡問題,所以還是贏得了廣泛的認可。典型的例子是XML和Java:XML文字的預設編碼就是UTF-8,而Java原始碼其實可以用UTF-8字元寫(JBuilder的使用者應該有印象)。另外還有開源軟體世界中大名鼎鼎的GTK 2.0,它使用UTF-8字元作為內部編碼。

說了這麼多,似乎話題有些扯遠了,許多Python愛好者可能已經開始著急:「這和Python有什麼關係呢?」好的,現在我們就把視線轉到Python的世界來。

第二節 Python的Unicode編碼系統

為了正確處理多語言文本,Python在2.0版後引入了Unicode字串。從那時起,Python語言中的字串就分為兩種:一種是2.0版之前就已經使用很久的傳統Python字串,一種則是新的Unicode字串。在Python語言中,我們使用unicode()內建函數對一個傳統Python字串進行“解碼”,得到一個Unicode字串,然後又透過Unicode字串的encode()方法對這個Unicode字串進行“編碼”,將其“編碼”成為傳統Python字串以上內容想必每個Python用戶都是爛熟於胸了。但你可知道,Python的Unicode字串並不是真正意義上的“Unicode編碼的字串”,而是遵循一種自己特有的規則。這個規則的內容簡單得很:

1、ASCII字元的Python Unicode編碼與它們的ASCII編碼相同。 也就是說,Python的Unicode字串中ASCII文字仍然是單字節長度編碼;

2、ASCII字元以外的字符,其編碼就是Unicode標準編碼的雙位元組(或四位元組)編碼。 (筆者猜想,之所以Python社群要製訂如此古怪的標準,可能是想保證ASCII字串的通用性吧)

通常在Python應用中,Unicode字串都是作為內部處理時使用,而終端顯示工作則由傳統的Python字串完成(實際上,Python的print語句根本無法列印出雙位元組的Unicode編碼字元)。在Python語言中,傳統Python字串就是所謂的「多位元組編碼」字串,用來表示各種被「編碼」成為具體字元集編碼的字串(例如GB、BIG5、KOI8-R、JIS、 ISO-8859-1,當然也有UTF-8);而Python Unicode字串則是「寬字元編碼」字串,表示從特定字元集編碼中「解碼」出來的Unicode資料。所以通常情況下,一個需要用到Unicode編碼的Python應用程式往往會以以下方式處理字串資料:


def foo(string, encoding = "gb2312"):
# 1. convert multi-byte string to wide character string
u_string = unicode(string, encoding)

# 2. do something
...

# 3. convert wide character string to printable multi-byte string
return u_string.encode(encoding)


我們可以舉出一個例子:經常在Red Hat Linux環境中使用PyGTK2進行XWindow程式設計的Python同道可能早就發現過這樣的情況:如果我們直接寫出如下語句:


import pygtk
pygtk.require('2.0')
import gtk

main = gtk.Window() # create a window
main.set_title("你好") # NOTICE!


這樣的語句在執行時會在終端機上出現這樣的警告:

Error converting from UTF-8 to 'GB18030': 轉換輸入中出現無效字元序列

且程式視窗標題不會被置為「你好」;但如果使用者安裝了中文的codec,並將上文的最後一句改為:


u_string = unicode('你好','gb2312')
main.set_title(u_string)


#則程式視窗標題將會被正確地設定為「你好」。這是為什麼呢?

原因很簡單。 gtk.Window.set_title()方法總是將自己接收的標題字串看做是一個Unicode字串。 PyGTK系統在接收到使用者的main.set_title()這項請求時,將得到的字串在某處做瞭如下處理:


class Window(gtk.Widget):
...
def set_title(self, title_unicode_string):
...
# NOTICE! unicode -> multi-byte utf-8
real_title_string = title_unicode_string.encode('utf-8')
...
# pass read_title_string to GTK2 C API to draw the title
...


我們看到,字串title_unicode_string在程式內部被「編碼」成了一個新的字串:real_title_string。顯然,這個real_title_string是一個傳統Python字串,而它的編碼用的是UTF-8。在上一節中筆者曾經提到過,GTK2的內部使用的字串都是按UTF-8編碼的,所以,GTK2核心系統在接收到real_title_string後可以正確顯示出標題來。

那麼,如果使用者輸入的標題是ASCII字串(例如:「hello world」),又當如何?我們回想一下Python Unicode字串的定義規則就不難發現,如果使用者的輸入是ASCII字串,則對其進行重編碼得到的就是其自身。也就是說,如果title_unicode_string的值是ASCII字串,則real_title_string與title_unicode_string的值將完全一致。而一個ASCII字串也就是一個UTF-8字串,把它傳遞給GTK2系統不會有任何問題。

以上我們舉的例子是關於Linux下的PyGTK2的,但類似的問題不僅出現在PyGTK。除了PyGTK之外,現今各種Python綁定的圖形包,如PyQT、Tkinter等,多多少少都會遇到與Unicode處理有關的問題。

現在我們弄清楚了Python的Unicode字串編碼機制,但是我們最想知道的問題還是沒有解決:我們如何讓Python支援用Unicode處理中文呢?這個問題我們將在下一節說明。

第三節如何讓Python的Unicode字串支援中文

看完這一節的標題,有一些Python同道們可能會有些不以為然:「為什麼一定要用Unicode處理中文呢?串也就足夠了。但是,如果涉及一些高級的字串操作,例如包含多國文字的正規表示式匹配、文字編輯、表達式分析等等,這些大量混雜了單字節和多位元組文本的操作如果用傳統字串處理就非常麻煩了。再說,傳統字串始終無法解決那該死的「半個字」問題。而如果我們可以使用Unicode,則這些問題都可以迎刃而解。所以,我們必須正視並設法解決中文Unicode的處理問題。 由上一節的介紹我們知道,如果要想利用Python的Unicode機制處理字串,只要能夠擁有一個能夠把多字節的中文編碼(包括GB編碼系列和BIG5系列)和Unicode編碼雙向轉換的編碼/解碼模組就可以了。依照Python的術語,這樣的編碼/解碼模組被稱為codec。於是接下來的問題就變成了:我們該如何寫這樣一個codec?

如果Python的Unicode機制是硬編碼在Python核心中的話,那麼給Python添加一個新的codec就將是一項艱苦卓絕的工作了。幸虧Python的設計者們沒有那麼傻,他們提供了一個擴充性極佳的機制,可以非常方便地為Python添加新的codecs。

Python的Unicode處理模組有三個最重要的組成部分:一是codecs.py文件,二是encodings目錄,三是aliases.py文件。前兩者都位於Python系統庫的安裝目錄之中(如果是Win32發行版,就在$PYTHON_HOME/lib/目錄下;如果是Red Hat Linux,就在/usr/lib/python-version/目錄下,其它系統可以照此尋找),而最後一個則位於encodings目錄下。接下來,我們分別對這三者加以說明。

先來看看codecs.py檔。這個檔案定義了一個標準的Codec模組應有的介面。其具體內容大家可以在自己的Python發行版中找到,在此不再贅述。依照codecs.py檔案的定義,一個完整的codec應該至少有三個類別和一個標準函數:

1、Codec類別用途:

用於將使用者傳入的緩衝區資料(一個buffer)作為一個傳統Python字串,並將

其「解碼」為對應的Unicode字串。一個完整的Codec類別定義必須提供Codec.decode()和

Codec.encode()兩個方法:

Codec.decode(input,

errors = "strict")<a href="http://www.php.cn/wiki/222.html" target="_blank"></a>用於將輸入的資料看做是傳統Python字串,並將其“解碼”,轉換成對應的Unicode字串。

參數:

input:輸入的buffer(可以是字串,也可以是任何可以轉換成字串表示的物件)

errors:發生轉換錯誤時的處理選擇。可選擇以下三種取值:

strict(預設值):如果發生錯誤,則拋出UnicodeError例外;

replace:如果發生錯誤,則選取一個預設的Unicode編碼代替之;

ignore:如果發生錯誤,則忽略這個字符,並繼續分析餘下的字符。

傳回值:

一個常數列表(tuple):首元素為轉換後的Unicode字串,尾元素為輸入資料的長度。

Codec.encode(input, errors = "strict")

用於將輸入的資料看做是Unicode字串,並將其“編碼”,轉換成對應的傳統Python字串。

參數:

input:輸入的buffer(通常是Unicode字串)

errors:發生轉換錯誤時的處理選擇。取值規則與Codec.decode()方法相同。

傳回值:

一個常數列表(tuple):首元素為轉換後的傳統Python字串,尾元素為輸入資料的長度。

2、StreamReader類別(通常應該繼承自Codec類別)

用于分析文件输入流。提供所有对文件对象的读取操作,如readline()方法等。

3、StreamWriter类(通常应该继承自Codec类)

用于分析文件输出流。提供所有对文件对象的写入操作,如writeline()方法等。

5、getregentry()函数

即“GET REGistry ENTRY”之意,用于获取各个Codec文件中定义的四个关键函数。其函数体统一为:


def getregentry():
return tuple(Codec().encode,Codec().decode,StreamReader,StreamWriter)


在以上提到的所有四个类中,实际上只有Codec类和getregentry()函数是必须提供的。必须提供前者是因为它是实际提供转换操作的模块;而后者则是Python系统获得Codec定义的标准接口,所以必须存在。至于StreamReader和StreamWriter,理论上应该可以通过继承codecs.py中的StreamReader和StreamWriter类,并使用它们的默认实现。当然,也有许多codec中将这两个类进行了改写,以实现一些特殊的定制功能。

接下来我们再说说encodings目录。顾名思义,encodings目录就是Python系统默认的存放所有已经安装的codec的地方。我们可以在这里找到所有Python发行版自带的codecs。习惯上,每一个新的codec都会将自己安装在这里。需要注意的是,Python系统其实并不要求所有的codec都必须安装于此。用户可以将新的codec放在任何自己喜欢的位置,只要Python系统的搜索路径可以找得到就行。

仅仅将自己写的codec安装在Python能够找到的路径中还不够。要想让Python系统能找到对应的codec,还必须在Python中对其进行注册。要想注册一个新的codec,就必须用到encodings目录下的aliases.py文件。这个文件中只定义了一个哈希表aliases,它的每个键对应着每一个codec在使用时的名称,也就是unicode()内建函数的第二个参数值;而每个键对应的值则是一个字符串,它是这个codec对应的那个处理文件的模块名。比如,Python默认的解析UTF-8的codec是utf_8.py,它存放在encodings子目录下,则aliases哈希表中就有一项表示其对应关系:

'utf-8' : 'utf_8', # the <a href="http://www.php.cn/code/8212.html" target="_blank">module</a> `utf_8' is the codec <a href="http://www.php.cn/wiki/125.html" target="_blank">for</a> UTF-8

同理,如果我们新写了一个解析‘mycharset'字符集的codec,假设其编码文件为mycodec.py,存放在$PYTHON_HOME/lib/site-packages/mycharset/目录下,则我们就必须在aliases哈希表中加入这么一行:

'mycharset' : 'mycharset.mycodec',

这里不必写出mycodec.py的全路径名,因为site-packages目录通常都在Python系统的搜索路径之中。

Python解释器在需要分析Unicode字符串时,会自动加载encodings目录下的这个aliases.py文件。如果mycharset已经在系统中注册过,则我们就可以像使用其它内建的编码那样使用我们自己定义的codec了。比如,如果按照上面的方式注册了mycodec.py,则我们就可以这样写:


my_unicode_string = unicode(a_multi_byte_string, &#39;mycharset&#39;)

print my_unicode_string.encode(&#39;mycharset&#39;)


现在我们可以总结一下要编写一个新的codec一共需要那些步骤:

首先,我们需要编写一个自己的codec编码/解码模块;

其次,我们要把这个模块文件放在一个Python解释器可以找到的地方;

最后,我们要在encodings/aliases.py文件中对其进行注册。

从理论上说,有了这三步,我们就可以将自己的codec安装到系统中去了。不过这样还不算完,还有一个小问题。有时候,我们出于种种原因,不希望随便修改自己的系统文件(比如,一个用户工作在一个集中式的系统中,系统管理员不允许别人对系统文件进行修改)。在以上介绍的步骤中,我们需要修改aliases.py文件的内容,这是一个系统文件。可如果我们不能修改它,难道我们就不能添加新的codec吗?不,我们当然有办法。

这个办法就是:在运行时修改encodings.aliases.aliases哈希表的内容。

还是使用上面那个假设,如果用户工作系统的管理员不允许用户把mycodec.py的注册信息写入aliases.py,那么我们就可以如此处理:

1、将mycodec.py放在一个目录下,比如/home/myname/mycharset/目录;

2、这样编写/home/myname/mycharset/init.py文件:


import encodings.aliases
# update aliases hash map
encodings.aliases.aliases.update({/
&#39;mycodec&#39; : &#39;mycharset.mycodec&#39;,/
}}


以后每次要使用Python时,我们可以将/home/myname/加入搜索路径,并且在使用自己的codec时预先执行:

import mycharset # execute the script in mycharset/init.py

这样我们就可以在不改动原有系统文件的情况下使用新的codecs了。另外,如果借助Python的site机制,我们还可以让这个import工作自动化。如果大家不知道什么是site,就请在自己的Python交互环境中运行:


import site
print site.doc


浏览一下site模块的文档,即可明白个中技巧。如果大家手头有Red Hat Linux v8,v9,还可以参考一下Red Hat的Python发行版中附带的日文codec,看看它是如何实现自动加载的。也许不少同道可能找不到这个日文的codec在哪里,这里列出如下:


  Red Hat Linux v8:在/usr/lib/python2.2/site-package/japanese/目录下;
  Red Hat Linux v9:在/usr/lib/python2.2/lib-dynload/japanese/目录下;


提示:请Red Hat用户注意site-packages目录下的japanese.pth文件,结合site模块的文档,相信马上就能豁然开朗。

结束语

记得当初笔者在Dohao论坛上夸下海口:“如果可以的话,我可以为大家编写一个(中文模块)”,现在回想起来,不禁为自己当初的不知天高地厚而汗颜。一个把自己所有的的时间都花在学习上,一个学期只学七门课程,还落得个两门课不及格的傻瓜研究生,哪里有什么资格在大家面前如此嚣张。现如今,第二个学期由于这两门课的缘故负担陡增(十门课呀!),家中老父老母还眼巴巴地等着自己的儿子能给他们挣脸。要想在有限的时间之内,既保证学习,又保证工作(我要承担导师的课程辅导工作,同时还有一个学校的教学改革方案需要我在其中挑大梁),已经是疲于应付,再加上一个中文模块……唉,请恕笔者分身乏术,不得不食言。

因此,笔者斗胆,在此和盘托出自己这半年以来的心得,只希望能够找到一批,不,哪怕是一个也好,只要是对这个项目感兴趣的同道中人,能够接下笔者已经整理出来的知识,把一个完整的(至少应该包含GB、BIG5、笔者个人认为甚至还应包括HZ码)中文模块编写出来,贡献给大家(不论是有偿的还是无偿的),那就是我们广大Python爱好者之福了。另外,Python的发行版至今尚未包括任何中文支持模块。既然我等平日深爱Python,如果我们的工作能因此为Python的发展做出一点贡献,何乐而不为呢?

附录 几个小小提示

1、LUO Jian兄已经编写了一个非常不错的中文模块(Dohao上有链接,文件名是showfile.zip,这个模块比我已经写完的草稿版本要快得多),同时支持GB2312和GB18030编码,可惜不支持BIG5。如果大家有兴趣,可以下载这个模块研究一下;

2、和其它字符集编码相比,中文模块有其特殊性,那就是其海量的字符数目。一些相对较小的字符集还好说,比如GB2312,可以利用哈希表查找。而对于巨大的GB18030编码,如果简单地将所有数据制成一个特大的编码对照表,则查询速度会慢得让人无法容忍(笔者在编写模块时最头疼的就是这一点)。如果要编写一个速度上能让人满意的codec,就必须考虑设计某种公式,能够通过简单地运算从一种编码推算出另一种来,或者至少能推算出它的大概范围。这就要求程序员要能对整个编码方案做统计,设法找到规律。笔者认为,这应该是编写中文模块时的最大难点。或许是数学功底实在太差的缘故,笔者费尽心机也未能找出一个规律来。希望能有数学高手不吝赐教;

3、中文编码分为两大派系:GB和BIG5。其中GB又分为GB2312、GBK和、GB18030三种编码,而BIG5也分为BIG5和BIG5-HKSCS两种(分别对应原始的BIG5和香港扩展版本)。虽然同一派系的编码可以向下兼容,但考虑到其字符数目庞大,为了加快查找速度,笔者个人认为还是将它们分开编码比较合理。当然,如果能够找到对应字符集的转换公式,则这种分离就没有必要了;

以上是詳解Unicode和Python的中文處理方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn