2010-03-24 77 views
7

我有一個MSSQL數據庫,我將其移植到SQLite/Django。我使用pymssql連接到數據庫並將文本字段保存到本地SQLite數據庫。轉換或去除「非法」Unicode字符

但是對於某些字符,它會爆炸。我得到這樣的投訴:

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

有什麼方法可以將字符轉換爲正確的unicode版本?或者將它們去掉?

回答

11

一旦你有字符串字符串s,而不是直接使用它作爲unicode obj,而是使用正確的編解碼器將其明確轉換,例如:

u = s.decode('latin-1') 

並使用u而不是s在代碼中遵循這一點(大概是寫入sqlite的部分)。假設latin-1是最初用來創建字節字符串的編碼 - 我們無法猜測,所以試着找出;-)。

作爲一般規則,我建議:不要在您的應用程序中將任何文本處理爲編碼字節字符串 - 在輸入後立即將它們解碼爲unicode對象,並且必要時在輸出之前將它們編碼回字節字符串。

+5

事實上,你必須知道你的文本是什麼編碼。幾乎沒有辦法解決這個問題。幸運的是,你的錯誤信息很明顯。幾乎可以肯定的是,由於存在0x97字符,你正在處理微軟惱人的cp1252。在拉丁語-1中,此代碼點包含一個幾乎從不使用的控制字符「保護區域結束」。由於0x97不是一個有效的字符前導字節,所以你將永遠不會看到utf-8的這個精確錯誤。另一方面,在cp1252中,這是非常普遍的模式。 – jcdyer 2010-03-24 15:48:27

11

當你解碼,只是通過「忽略」剝離這些字符

有剝離的一些方法/轉換那些

'replace': replace malformed data with a suitable replacement marker, such as '?' or '\ufffd' 

'ignore': ignore malformed data and continue without further notice 

'backslashreplace': replace with backslashed escape sequences (for encoding only) 

測試

>>> "abcd\x97".decode("ascii") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can't decode byte 0x97 in position 4: ordinal not in range(128) 
>>> 
>>> "abcd\x97".decode("ascii","ignore") 
u'abcd' 
+12

即使使用'ignore',python也會拋出錯誤。似乎沒有解碼/編碼的組合,我可以去除任何無用的UTF-8字符,我無法給出任何細節。 – user1244215 2013-12-06 01:17:46