2016-01-21 160 views
2

我試圖轉換一個包含中文字符的漢化字符轉換成latin1編碼的本地化文件。用Python編碼中文到Latin1的字符編碼

然而,當我運行python腳本我得到這個錯誤...

UnicodeDecodeError: 'ascii' codec can't decode byte 0xb9 in position 0: ordinal not in range(128) 

這裏是我的Python腳本,它本質上只是需要用戶輸入轉換所述文件。然後轉換文件(所有以[[或者爲空]開頭的行都應該跳過)...需要轉換的部分始終位於列表中的索引1處。

# coding: utf8 

# Enter File Name 
file_name = raw_input('Enter File Path/Name To Convert: ') 

# Open the File we Write too... 
write_file = open(file_name + "_temp", 'w+') 

# Open the File we Read From... 
read_file = open(file_name) 

with open(file_name) as file_to_write: 
    for line in file_to_write: 
     # We ignore any line that starts with [] or is empty... 
     if line and line[0:1] != '[': 
      split_string = line.split("=") 
      if len(split_string) == 2: 
       write_file.write(split_string[0] + "=" + split_string[1].encode('gbk').decode('latin1') + "\n") 
      else: 
       write_file.write(line) 
     else: 
      write_file.write(line) 



# Close File we Write too.. 
write_file.close() 

# Close File we read too.. 
read_file.close() 

並且例如配置文件是...

[Example] 
Password=密碼 

輸出應被轉換爲...

[Example] 
Password=±K½X 
+0

http://www.joelonsoftware.com/articles/Unicode.html <在這裏閱讀。它有助於 – jsbueno

回答

1

LATIN1編碼不能代表中國字符。如果你所有的輸出都是latin1,你可以得到更好的結果,是轉義序列。

您正在使用Python 2.x - Python3.x以文本形式打開文件,並在讀取時自動將讀取的字節解碼爲(unicode)字符串。

在Python2,當你讀一個文件,你得到字節 - 你有責任解碼這些字節的文本(在Python 2.x的Unicode對象) - 處理它們,並重新編碼他們所需的編碼在將信息記錄到另一個文件時。

因此,行,上面寫着:

write_file.write(split_string[0] + "=" + split_string[1].encode('gbk').decode('latin1') + "\n") 

應該是:

write_file.write(split_string[0] + "=" + split_string[1].decode('gbk').encode('latin1', errors="escape") + "\n") 

代替。

現在請注意,我將參數errors="escape"添加到了decode調用中 - 正如我上面所說的一樣,latin1是233個左右字符的字符集 - 它包含拉丁字母和最常用的重音字符(「 「...等等),一些基督教和數學符號,但沒有其他語言的字符。

如果您必須將這些文本表示爲文本,則應使用utf-8編碼 - 並配置您使用的任何軟件,以便將生成的文件轉換爲該編碼。

這就是說,你在做什麼只是一個可怕的做法。除非你打開一個真正的噩夢般的文件,它已知包含不同編碼的文本,你應該將所有文本解碼爲unicode,然後將它們全部重新編碼 - 而不僅僅是數據的非ASCII碼部分字符。只是不這樣做,如果你有其他的,GBK不兼容,在原文件的字符,否則,你的內循環可能還有是:

with open(file_name) as read_file, open(file_name + "_temp", "wt") as write_file: 
    for line in read_file: 
     write_file.write(line.decode("gbk").encode("utf-8") 

至於你的「示例輸出」 - 這僅僅是_very_same文件,即第一個文件中的相同字節。顯示行的程序:「Password =密碼」是用GBK編碼「看到」文件,另一個程序「看到」完全相同的字節,但將它們解釋爲latin1。你不應該從一個轉換到另一個。

+0

我無法改變加載這些本地化文件的程序如何讀取它們,但它確實將它們讀爲latin1。這就是說....有沒有辦法只是將文件編碼更改爲latin1,所以它在所有情況下讀爲latin1? 您的更改不會產生此錯誤.... UnicodeDecodeerror:'gbk'編解碼器無法解碼位置2-3中的字節:非法多字節序列 – Ricky

+0

不,沒有辦法固有地知道文本文件的編碼。 閱讀它的程序必須被「告知」它應該被讀作latin1。 Latin1是一個特別有趣的編解碼器,其中所有字節值都是有效的,因此可以讀取文件爲latin1並將其寫回,即使它具有其他編碼,也不會破壞信息或獲取錯誤。 – jsbueno

+0

有趣...你知道我可以如何解決新的錯誤嗎? – Ricky