小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

小結Python的中文處理

 豆芽愛尚閱 2014-07-11
  1. Python的中文處理

  2. 一、使用中文字符
  3.     在python源碼中如果使用了中文字符,運行時會有錯誤,解決的辦法是在源碼的開頭部分加入字符編碼的聲明,下面是一個例子:
  4.       #!/usr/bin/env python
  5.       # -*- coding: cp936 -*-
  6.     Python Tutorial中指出,python的源文件可以編碼ASCII以外的字符集,最好的做法是在#!行后面用一個特殊的注釋行來定義字符集:
  7.         # -*- coding: encoding -*-
  8. 根據(jù)這個聲明,Python會嘗試將文件中的字符編碼轉為encoding編碼,并且,它盡可能的將指定地編碼直接寫成Unicode文本。
  9.     注意,coding:encoding只是告訴Python文件使用了encoding格式的編碼,但是編輯器可能會以自己的方式存儲.py文件,因此最后文件保存的時候還需要編碼中選指定的ecoding才行。

  10. 二、中文字符的存儲
  11.         >>> str = u"中文"
  12.         >>> str
  13.         u'\xd6\xd0\xce\xc4'
  14.         >>> str = "中文"
  15.         >>> str
  16.         '\xd6\xd0\xce\xc4'
  17.     u"中文"只是聲明unicode,實際的編碼并沒有變。這樣子就發(fā)生變化了:
  18.         >>> str = "中文"
  19.         >>> str
  20.         '\xd6\xd0\xce\xc4'
  21.         >>> str = str.decode("gb2312")
  22.         >>> str
  23.         u'\u4e2d\u6587'
  24. 更進一步:
  25.         >>> s = '中文'
  26.         >>> s.decode('gb2312')
  27.         u'\u4e2d\u6587'
  28.         >>> len(s)
  29.         4
  30.         >>> len(s.decode('gb2312'))
  31.         2
  32.         >>> s = u'中文'
  33.         >>> len(s)
  34.         4
  35.         >>> s = '中文test'
  36.         >>> len(s)
  37.         8
  38.         >>> len(s.decode('gb2312'))
  39.         6
  40.         >>> s = '中文test,'
  41.         >>> len(s)
  42.         10
  43.         >>> len(s.decode('gb2312'))
  44.         7
  45.     可以看出,對于實際Non-ASCII編碼存儲的字符串,python可以正確的識別出其中的中文字符以及中文上下文中的標點符號。
  46.     前綴“u”表示“后面這個字符串“是一個Unicode字符串”,這僅僅是一個聲明,并不表示這個字符串就真的是Unicode了;就好比某正太聲稱自己已滿18歲,但實際上他的真實年齡并不確定,現(xiàn)在體育界年齡造假可不稀罕幺!
  47.     那么聲明成u有什么作用呢?對于Python來說,只要你聲明某字符串是Unicode,它就會用Unicode的一套機制對它進行處理。比方說,做字符串操作的時候會動用到內(nèi)部的Unicode處理函數(shù),保存的時候以Unicode字符(雙字節(jié))進行保存。等等。顯而易見,對于一個實際上并不是Unicode的字符串,做Unicode動作的處理,是有可能會出問題的。u前綴只適用于你的字符串常量真的是Unicode的情況。

  48. 三、中文字符的IO操作
  49.     用python處理字符串很容易,但是在處理中文的時候需要注意一些問題。比如:
  50.         a = "我們是python愛好者"
  51.         print a[0]
  52. 只能輸出“我”字的前半部分,要想輸出整個的“我”字還需要:
  53.         b = a[0:2]
  54.         print b
  55. 才行,很不方便,并且當一段文本中同時有中英文如何處理?最好的辦法就是轉換為unicode。像這樣:
  56.         c = unicode(a, "gb2312")
  57.         print c[0]
  58. 這個時候c的下標對應的就是每一個字符,不再是字節(jié),并且通過len(c)就可以獲得字符數(shù)!還可以很方便的轉換為其他編碼,比如轉換為utf-8:
  59.        d = c.encode("utf-8")

  60. 四、<type 'str’>和<type 'unicode’>
  61. <type 'str’>將字符串看作是字節(jié)的序列,而<type 'unicode’>則將其看作是字符的序列,單個字符可能占用多個字節(jié);字節(jié)相對于字符,其在存儲層次中更低一些。
  62. str轉換為unicode要decode,可以這樣想,因為要把字節(jié)序列解釋成字符序列,字節(jié)序列是底層的存放方式,解碼(decode)成更高層的字符以便使用;同理,unicode轉換為str要encode,就象信息編碼(encode)后才存儲一樣:
  63.         s.decode(encoding)    <type 'str'> to <type 'unicode'>
  64.         u.encode(encoding)    <type 'unicode'> to <type 'str'>
  65.     例如:
  66.         >>> s = 'str'
  67.         >>> type(s)
  68.         <type 'str'>
  69.         >>> type(s.decode())
  70.         <type 'unicode'>
  71.         >>> s = u'str'
  72.         >>> type(s)
  73.         <type 'unicode'>
  74.         >>> type(s.encode())
  75.         <type 'str'>
  76. 處理中文數(shù)據(jù)時最好采用如下方式:
  77.    1. Decode early(盡早decode, 將文件中的內(nèi)容轉化成unicode再進行下一步處理)
  78.    2. Unicode everywhere (程序內(nèi)部處理都用unicode)
  79.    3. Encode late (最后encode回所需的encoding, 例如把最終結果寫進結果文件)
  80. 下面是一個簡單的演示,用re庫查詢一個中文字符串并打?。?br>
  81.     >>> p = re.compile(unicode("測試(.*)", "gb2312"))
  82.     >>> s = unicode("測試一二三", "gb2312")
  83.     >>> for i in p.findall(s):
  84.                   print i.encode("gb2312")
  85.     一二三

  86. 五、跨平臺處理技巧
  87.     如果一個project必須在兩個平臺上開發(fā),程序應該使用同樣的encoding,比如要求所有的文件都使用UTF-8,如果實在不能統(tǒng)一(一般是為了滿足許多所謂專家學者莫名其妙的要求),可以退而求其次,用當前系統(tǒng)編碼決定文件內(nèi)的編碼:
  88.         import locale
  89.         import string
  90.         import re
  91.         #根據(jù)當前系統(tǒng)的encoding構造需要的編碼取值
  92.         lang = string.upper(locale.setlocale(locale.LC_ALL, ""))
  93.         textencoding = None
  94.         #檢查編碼的值是不是滿足我們需要的情況
  95.         if re.match("UTF-8", lang) != None:
  96.             # UTF-8編碼
  97.             textencoding = "utf-8"
  98.         elif re.match(r"CHINESE|CP936", lang):
  99.             # Windows下的GB編碼
  100.             textencoding = "gb18030"
  101.         elif re.match(r"GB2312|GBK|GB18030", lang):
  102.             # Linux下的GB編碼
  103.             textencoding = "gb18030"
  104.         else:
  105.             # 其他情況,拋個錯誤吧
  106.             raise UnicodeError
  107.         fd = file(filename, "r")
  108.         fulltextlist = fd.readlines()
  109.         # 把每一行轉換成unicode
  110.         for each in len(fulltextlist):
  111.             fulltextlist[i] = unicode(each, textencoding)
  112.         fd.close()
  113.         # 如果要打印的話,可以用text.encode(encoding)來恢復成多字節(jié)編碼

  114. 小結
  115.     一個比較一般的Python中文處理的流程:
  116.     * 將欲處理的字符串用unicode函數(shù)以正確的編碼轉換為Unicode                     
  117.     * 在程序中統(tǒng)一用Unicode字符串進行操作                                          
  118.     * 輸出時,使用encode方法,將Unicode再轉換為所需的編碼                        
  119. 有幾點要說明一下:
  120.     * 所謂“正確的”編碼,指得是指定編碼和字符串本身的編碼必須一致。這個其實并不那么容易判斷,一般來說,我們直接輸入的簡體中文字符,有兩種可能的編碼:GB2312(GBK、GB18030)、以及UTF-8
  121.     * encode成本地編碼的時候,必須要保證目標編碼中存在欲轉換字符的內(nèi)碼。encode這種操作一般是通過一個本地編碼對應Unicode的編碼轉換表來進行的,事實上每個本地編碼只能映射到Unicode的一部分。但是映射的區(qū)域是不同的,比如Big-5對應的Unicode的編碼范圍和 GBK對應的就不一樣(實際上這兩個編碼有部分范圍是重疊的)。所以,Unicode的一些字符(比如本身就是從GB2312轉換來的那些),可以映射到 GBK,但未必可以映射到Big-5,如果你想轉換到Big-5,很有可能就會出現(xiàn)編碼找不到的異常。但UTF-8的碼表范圍實際上和Unicode是一樣的(只是編碼形式不同而已),所以,理論上來說,任何本地編碼的字符,都可以被轉換到UTF-8
  122.     * GB2312、GBK、GB18030本質上是同一種編碼標準。只是在前者的基礎上擴充了字符數(shù)量
  123.     * UTF-8和GB編碼不兼容

  124. 參考資料
  125. 1、[url]http://bbs3./thread-1389703-1-2.html[/url]
  126. 2、Python的中文處理及其它
  127.    [url]http://www./?p=38[/url]
  128. 3、Python處理中文的時候的一些小技巧
  129.    [url]http:///?p=461[/url]
  130. 4、Unicode In Python, Completely Demystified. Kumar McMillan
  131.    [url]http:///talks/unicode[/url]
  132. 5、python中文處理好方法
  133.    [url]http://www./bbs/viewthread.php?tid=311[/url]
  134. 6、Python的中文處理
  135.    [url]http://hi.baidu.com/mrsz/blog/item/7812a5018c2cf2031d9583d2.html[/url]
復制代碼

[ 本帖最后由 pFreeStyle 于 2009-4-16 09:24 編輯 ]

Python的中文處理.pdf

108.54 KB, 下載次數(shù): 581

PDF版

Python的中文處理.pdf

124.4 KB, 下載次數(shù): 683

添加了異常處理的介紹
  1. 六、異常處理

  2.     編碼encoding發(fā)生在Unicode字符串轉換為字節(jié)序列時,而解碼decoding發(fā)生在字節(jié)序列轉換為Unicode字符串時(encoding always takes a Unicode string and returns a bytes sequence, and decoding always takes a bytes sequence and returns a Unicode string)。

  3. UnicodeDecodeError
  4. UnicodeDncodeError通常發(fā)生在將str字符串解碼為特定Unicode字符串時。由于不同的編碼只能映射部分str字符串到對應的Unicode字符,所以遇到一些字符時解碼會失敗。

  5. UnicodeEncodeError
  6.     UnicodeEncodeError通常發(fā)生在將Unicode字符串編碼為特定字節(jié)序列時。由于不同的編碼只能映射部分Unicode字符到對應的str字符串,所以遇到一些字符時編碼會失敗。

  7. 處理python編碼轉換時的UnicodeDecodeError異常

  8.     python提供的unicode轉換不像iconv或是mbstowcs之類的方便。如果轉換一段unicode("1234中文",'ascii') 到utf8,會直接出現(xiàn)UnicodeDecodeError的錯誤。如果在你能預知字串符的編碼的時候,比如你用unicode('1234中文', 'gbk') 就不會出現(xiàn)錯誤;不過很多時候,會出現(xiàn)CJK混合的情況,如果要做到將一段CJK文件轉換成unicode可能就行不通了。好在python的codecs提供了register_error這個功能:
  9.         register_error(name, error_handler)
  10. 原理很簡單,不過要先看unicode是如何處理異常的。unicode這個函數(shù)是將一段string按輸入的編碼轉換成目標的編碼,如果出現(xiàn)了不與輸入編碼相符的,會出現(xiàn)一個UnicodeDecodeError的異常,通常有三種處理方法:strict、replace、ignore;默認是 strict,就是直接raise UnicodeDecodeError。通過register_error,我們也可以有自己的處理方法,如果遇到與輸入的編碼不符的時候,我們就自己識別,比如GBK、BIG5、JP的字符。
  11.     def cjk_replace(exc):
  12.         if not isinstance(exc, UnicodeDecodeError):
  13.             raise TypeError("don't know how to handle %r" % exc)

  14.         if exc.end + 1 > len(exc.object):
  15.             raise TypeError('unknown codec ,the object too short!')

  16.         ch1 = ord(exc.object[exc.start:exc.end])
  17.         newpos = exc.end + 1
  18.         ch2 = ord(exc.object[exc.start + 1:newpos])
  19.         sk = exc.object[exc.start:newpos]


  20.         if 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0x7E<=ch2<=0xFE): # GBK
  21.             return (unicode(sk,'cp936'), newpos)

  22.         if 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0xA1<=ch2<=0xFE): # BIG5
  23.             return (unicode(sk,'big5'), newpos)

  24.         raise TypeError('unknown codec !')

  25.     codecs.register_error("cjk_replace", cjk_replace)
  26. 我們的cjk_replace現(xiàn)在只能處理GBK與BIG5的,因為我對編碼也不是特別了解,只是大概知道GBK與BIG5的,不太了解JP的。在 cjk_replace這個函數(shù)里,我們對不認識的文字進行手工識別,如果認識的編碼,就用正確的方法,并返回編碼后的內(nèi)容與新的pos,比如“1234中文”,在pos為4的時候,會調(diào)用我們的cjk_replace,我們會返回一個從gbk轉換成utf8的“中”字,并返回下個正確的位置“文”的起始位置。當然了,處理“文”的時候,還會再調(diào)用一次。下面看看是如何使用的:
  27.         filedata = open('test.txt','r).read()    #gbk and big5 file
  28.         data = unicode(filedata,'ascii','cjk_replace').encode('utf8')

  29. 7、 UnicodeDecodeError
  30.       [url]http://wiki./moin/UnicodeDecodeError[/url]
  31. 8、 UnicodeEncodeError
  32.       [url]http://wiki./moin/UnicodeEncodeError[/url]
  33. 9、 如何處理python編碼轉換時的UnicodeDecodeError異常
  34.       [url]http://blog./u/8873/showart_1009737.html[/url]
  35. 10、codecs — Codec registry and base classes
  36.        [url]http://docs./library/codecs.html[/url]

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多