字串在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)下面也是沒有問題的了!~
轉載自:http://blog.chinaunix.net/u2/84280/showart_2207975.html