python中文decode和encode轉碼

來源:互聯網
上載者:User

轉載:http://blog.chinaunix.net/u2/84280/showart_2207975.html

字串在Python內部的表示是unicode編碼,因此,在做編碼轉換時,通常需要以unicode作為中間編碼,即先將其他編碼的字串解碼(decode)成unicode,再從unicode編碼(encode)成另一種編碼。

decode的作用是將其他編碼的字串轉換成unicode編碼,如str1.decode('gb2312'),表示將gb2312編碼的字串str1轉換成unicode編碼。

encode的作用是將unicode編碼轉換成其他編碼的字串,如str2.encode('gb2312'),表示將unicode編碼的字串str2轉換成gb2312編碼。

因此,轉碼的時候一定要先搞明白,字串str是什麼編碼,然後decode成unicode,然後再encode成其他編碼

代碼中字串的預設編碼與代碼檔案本身的編碼一致。
如:s='中文'
如果是在utf8的檔案中,該字串就是utf8編碼,如果是在gb2312的檔案中,則其編碼為gb2312。

(與代碼本身的編碼是一致的!)

測試:
我的eclipse裡面代碼為utf-8編碼的。然後我這樣寫代碼
s="你好"
s=s.decode('gb2312').encode('utf-8')
print s
報錯:
UnicodeDecodeError: 'gb2312' codec can't decode bytes in position 2-3: illegal multibyte sequence
原因:因為我的檔案為UTF-8編碼的。所以你想用gb2312將其轉成unicode是不可能的。
所以正確的寫法應當是:
s="你好"
print s
s=s.decode('utf-8').encode('utf-8') 要用UTF-8來做編碼
print s
哈哈發現列印出來的是亂碼那隻能說明一件事情就是我的eclipse控制台是GB2312的編碼!

請看:
如何獲得系統的預設編碼?
#!/usr/bin/env python
#coding=utf-8
import sys
print sys.getdefaultencoding()

該段程式在英文WindowsXP上輸出為:ascii 。我發現我的linux上面也是ascii編碼。所以我想列印出來看到的亂碼是正常的。因為我其實是utf-8編碼的。

在某些IDE中,字串的輸出總是出現亂碼,甚至錯誤,其實是由於IDE的結果輸出控制台自身不能顯示字串的編碼,而不是程式本身的問題。(是的。我的eclipse控制台就是gb2312的編碼所以我檔案儲存為utf-8的時候然後再通過列印是亂碼了!)

1、讀檔案命令肯定是:
myfile = codecs.open("c.html","r","utf-8") 因為我用gb2312來讀的話報錯

心得:檢查一個字串是什麼編碼只需要看一下decode 如果用gb2312來decode沒報錯的話就表示是gb2312
如果用utf-8來decode沒有報錯的話就表示是utf-8

現在遇到一個問題就是
請看:
myfile = codecs.open("c.html","r","utf-8")
str = myfile.read()                               
content = str.replace("\n"," ")  
content = content.encode('utf-8')
print content
沒有報錯
再看:
myfile = codecs.open("c.html","r","utf-8")
str = myfile.read()                                 #顯示中文
content = str.replace("\n"," ")  
content = content.encode('gb2312')                 用gb2312
print content
報錯:UnicodeEncodeError: 'gb2312' codec can't encode character u'\u2014' in position 12628

再看:
myfile = codecs.open("d.html","r","utf-8")
str = myfile.read()                                 #顯示中文
content = str.replace("\n"," ")  
content = content.encode('gb2312')                 用gb2312
print content
沒問題
myfile = codecs.open("d.html","r","utf-8")
str = myfile.read()                                 #顯示中文
content = str.replace("\n"," ")  
content = content.encode('utf-8')                
print content
也沒問題

結論:我想是c.html頁面裡面 存在某些 特殊字元 只支援utf-8編碼。而不支援gb2312的編碼!
而d.html沒有這種特殊字元。這也就解釋了為什麼
有的檔案並沒有發生我們想像中的問題!

所以我感覺開啟檔案肯定是用utf-8來讀取得到一個unicode編碼值!
然後對其做utf-8的編碼處理。因為如果你做gb2312處理的話就會報錯了!

接著:
我看了一下我的Regex發現如果用gb2312做解碼處理的話一樣會報錯。所以斷定肯定是utf-8編碼了!
regex3 = regex3.decode('utf-8')
print type(regex3)                #返回為unicode碼了!
print regex3                      #居然列印為正常的中文顯示了 奇怪

嘗試解決辦法:
1、全部用unicode處理
即正則我用regex3 = regex3.decode('utf-8') 將其處理成 unicode編碼了。然後內容也
print type(content) 也是unicode編碼。結果還是不行!

難道是我的linux終端的編碼引起的嗎?我看了一下
locale 發現是GBK的終端的。即只有GBK編碼才能顯示出來為中文的!
於是我將
regex3 = regex3.decode('utf-8').encode('gb2312') 編碼成gb2312結果可以顯示中文!

OK。我又將我的內容也一起弄成GB2312
content = content.encode('gb2312','ignore')
print content                 也可以成功列印出來中文。

我想這個時候應該沒有什麼問題了吧。結果一用正則又死掉了。昏死!!!!!!!

換另外一個好的檔案測試下看看:換了之後發現沒死而且成功了!

所以我覺得:肯定是這個檔案裡面的某些內容與正則匹配出現了衝突!導致的!

繼續跟蹤:
出現如下的情況
myfile = codecs.open("01.htm","r","utf-8","ignore")             
str = myfile.read()                              
content = str.replace("\n"," ")
print type(content)                               #發現是unicode碼
regex3 = 'class=wpcpsCSS>([^<]+)(?:.*?wpcppb_CSS> ([0-9]+) </span>)?.*?(?:.*?(已被關閉))?.*?([0-9]+)個回答.*?([0-9]+)次瀏覽.*?(?:<div class=wpcptfCSS>.*?user\?userid=([0-9]+).*?>(.*?)</a> </div>.*?)?(?:user\?userid=([0-9]+)")? class="wpfitCSS[^"]+">([^<]+).*?class=wpcptsCSS>([^<]+).*?([0-9.]{9,}\*).*?class=wpcpdCSS>(.*?)</div>
<div class=wpcpfCSS>'
content = content.encode('utf-8')
p=re.compile(regex3)
results = p.findall(content)

沒有什麼問題可以成功出來結果。但是我
將content = content.encode('gb2312') 的話就發現 死掉了!
說明我的內容content與我的正則的編碼其實是不一樣的!
我現在將我的正則也調成gb2312來測試。結果發現可以出來。而且我的結果
results = p.findall(content)
for ele in results:
    print ele[0],ele[1],ele[2],ele[3],ele[4],ele[5],ele[6],ele[7],ele[8],ele[9],ele[10]
在eclipse(預設為gb2312)下面也是沒有問題的了!~

所以我想:如果content是GBK那正則的內容也應當是GBK 即兩者的編碼一定要保持一致!否則就會出現死掉程式的情況!

現在我這樣來處理
全部使用unicode編碼處理

myfile = codecs.open("right.html","r")   
str = myfile.read()                                
content = str.replace("\n"," ")
content = content.decode('utf-8','ignore')     #使用utf-8解碼出來
都使用unicode編碼吧
現在正則也用
regex3 = regex3.decode('utf-8','ignore') 使用utf-8搞成unicode編碼

OK現在再來測試!

結論:
解決正則出現中文的BUG結論:
1、開啟檔案
myfile = codecs.open("right.html","r")
不需要設定其編碼的!

設定編碼格式
str = myfile.read()                             
content = str.replace("\n"," ")
content = content.decode('utf-8','ignore')   #使用utf-8解碼成unicode格式

正則:
regex3 = regex3.decode('utf-8','ignore')    #正則也統一使用utf-8解碼成unicode格式

然後就可以
p=re.compile(regex3)
results = p.findall(content)
調用正則了!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.