python的中文處理
一、使用中文字元
在python原始碼中如果使用了中文字元,執行時會有錯誤,解決的辦法是在原始碼的開頭部分加入字元編碼的宣告,下面是乙個例子:
#!/usr/bin/env python
# -*- coding: cp936 -*-
python tutorial中指出,python的原始檔可以編碼ascii以外的字符集,最好的做法是在#!行後面用乙個特殊的注釋行來定義字符集:
# -*- coding: encoding -*-
根據這個宣告,python會嘗試將檔案中的字元編碼轉為encoding編碼,並且,它盡可能的將指定地編碼直接寫成unicode文字。
注意,coding:encoding只是告訴python檔案使用了encoding格式的編碼,但是編輯器可能會以自己的方式儲存.py檔案,因此最後檔案儲存的時候還需要編碼中選指定的ecoding才行。
二、中文字元的儲存
>>> str = u"中文"
>>> str
u'\xd6\xd0\xce\xc4'
>>> str = "中文"
>>> str
'\xd6\xd0\xce\xc4'
u"中文"只是宣告unicode,實際的編碼並沒有變。這樣子就發生變化了:
>>> str = "中文"
>>> str
'\xd6\xd0\xce\xc4'
>>> str = str.decode("gb2312")
>>> str
u'\u4e2d\u6587'
更進一步:
>>> s = '中文'
>>> s.decode('gb2312')
u'\u4e2d\u6587'
>>> len(s)
4>>> len(s.decode('gb2312'))
2>>> s = u'中文'
>>> len(s)
4>>> s = '中文test'
>>> len(s)
8>>> len(s.decode('gb2312'))
6>>> s = '中文test,'
>>> len(s)
10>>> len(s.decode('gb2312'))
7可以看出,對於實際non-ascii編碼儲存的字串,python可以正確的識別出其中的中文字元以及中文上下文中的標點符號。
字首「u」表示「後面這個字串「是乙個unicode字串」,這僅僅是乙個宣告,並不表示這個字串就真的是unicode了;就好比某正太聲稱自己已滿18歲,但實際上他的真實年齡並不確定,現在體育界年齡造假可不稀罕么!
那麼宣告成u有什麼作用呢?對於python來說,只要你宣告某字串是unicode,它就會用unicode的一套機制對它進行處理。比方說,做字串操作的時候會動用到內部的unicode處理函式,儲存的時候以unicode字元(雙位元組)進行儲存。等等。顯而易見,對於乙個實際上並不是unicode的字串,做unicode動作的處理,是有可能會出問題的。u字首只適用於你的字串常量真的是unicode的情況。
三、中文字元的io操作
用python處理字串很容易,但是在處理中文的時候需要注意一些問題。比如:
a = "我們是python愛好者"
print a[0]
只能輸出「我」字的前半部分,要想輸出整個的「我」字還需要:
b = a[0:2]
print b
才行,很不方便,並且當一段文字中同時有中英文如何處理?最好的辦法就是轉換為unicode。像這樣:
c = unicode(a, "gb2312")
print c[0]
這個時候c的下標對應的就是每乙個字元,不再是位元組,並且通過len(c)就可以獲得字元數!還可以很方便的轉換為其他編碼,比如轉換為utf-8:
d = c.encode("utf-8")
四、和將字串看作是位元組的序列,而則將其看作是字元的序列,單個字元可能占用多個位元組;位元組相對於字元,其在儲存層次中更低一些。
str轉換為unicode要decode,可以這樣想,因為要把位元組序列解釋成字串行,位元組序列是底層的存放方式,解碼(decode)成更高層的字元以便使用;同理,unicode轉換為str要encode,就象資訊編碼(encode)後才儲存一樣:
s.decode(encoding) to
u.encode(encoding) to
例如:>>> s = 'str'
>>> type(s)
>>> type(s.decode())
>>> s = u'str'
>>> type(s)
>>> type(s.encode())
處理中文資料時最好採用如下方式:
1. decode early(盡早decode, 將檔案中的內容轉化成unicode再進行下一步處理)
2. unicode everywhere (程式內部處理都用unicode)
3. encode late (最後encode回所需的encoding, 例如把最終結果寫進結果檔案)
下面是乙個簡單的演示,用re庫查詢乙個中文字串並列印:
>>> p = re.compile(unicode("測試(.*)", "gb2312"))
>>> s = unicode("測試一二三", "gb2312")
>>> for i in p.findall(s):
print i.encode("gb2312")
一二三五、跨平台處理技巧
如果乙個project必須在兩個平台上開發,程式應該使用同樣的encoding,比如要求所有的檔案都使用utf-8,如果實在不能統一(一般是為了滿足許多所謂專家學者莫名其妙的要求),可以退而求其次,用當前系統編碼決定檔案內的編碼:
import locale
import string
import re
#根據當前系統的encoding構造需要的編碼取值
lang = string.upper(locale.setlocale(locale.lc_all, ""))
textencoding = none
#檢查編碼的值是不是滿足我們需要的情況
if re.match("utf-8", lang) != none:
# utf-8編碼
textencoding = "utf-8"
elif re.match(r"chinese|cp936", lang):
# windows下的gb編碼
textencoding = "gb18030"
elif re.match(r"gb2312|gbk|gb18030", lang):
# linux下的gb編碼
textencoding = "gb18030"
else:
# 其他情況,拋個錯誤吧
raise unicodeerror
fd = file(filename, "r")
fulltextlist = fd.readlines()
# 把每一行轉換成unicode
for each in len(fulltextlist):
fulltextlist[i] = unicode(each, textencoding)
fd.close()
# 如果要列印的話,可以用text.encode(encoding)來恢復成多位元組編碼
小結乙個比較一般的python中文處理的流程:
* 將欲處理的字串用unicode函式以正確的編碼轉換為unicode
* 在程式中統一用unicode字串進行操作
* 輸出時,使用encode方法,將unicode再轉換為所需的編碼
有幾點要說明一下:
* 所謂「正確的」編碼,指得是指定編碼和字串本身的編碼必須一致。這個其實並不那麼容易判斷,一般來說,我們直接輸入的簡體中文本元,有兩種可能的編碼:gb2312(gbk、gb18030)、以及utf-8
* encode成本地編碼的時候,必須要保證目標編碼中存在欲轉換字元的內碼。encode這種操作一般是通過乙個本地編碼對應unicode的編碼轉換表來進行的,事實上每個本地編碼只能對映到unicode的一部分。但是對映的區域是不同的,比如big-5對應的unicode的編碼範圍和 gbk對應的就不一樣(實際上這兩個編碼有部分範圍是重疊的)。所以,unicode的一些字元(比如本身就是從gb2312轉換來的那些),可以對映到 gbk,但未必可以對映到big-5,如果你想轉換到big-5,很有可能就會出現編碼找不到的異常。但utf-8的碼表範圍實際上和unicode是一樣的(只是編碼形式不同而已),所以,理論上來說,任何本地編碼的字元,都可以被轉換到utf-8
* gb2312、gbk、gb18030本質上是同一種編碼標準。只是在前者的基礎上擴充了字元數量
* utf-8和gb編碼不相容
參考資料
1、[url]
2、python的中文處理及其它
[url]
3、python處理中文的時候的一些小技巧
[url]
4、unicode in python, completely demystified. kumar mcmillan
[url]
5、python中文處理好方法
[url]
6、python的中文處理
[url]
Python的中文處理
一 使用中文字元 在python原始碼中如果使用了中文字元,執行時會有錯誤,解決的辦法是在原始碼的開頭部分加入字元編碼的宣告,下面是乙個例子 usr bin env python coding cp936 python tutorial中指出,python的原始檔可以編碼ascii以外的字符集,最好...
Python處理中文
用python寫了個從一堆中文微博中抽取電影票房資料的程式,處理中文編碼問題非常麻煩,有以下經驗 1,在正規表示式中的中文應該用 u x的形式,正規表示式字串還要以ur為字首 u表示unicode,r表示raw,即忽略c 形式的轉義字元 2,各種編碼都統一成utf8的時候世界終於清靜了 4,原始碼開...
python中文處理
1.多位元組問題必須要全部轉成unicode再處理,否則就會有問題,比如中文gbk編碼的 和珅 其中的珅的後半位元組和 的一樣的,所以在處理的時候會有問題,如下我們用re.split來分割 用正則分隔某個字串 def split str,patternlist unicodestr str.deco...