[英]How do I better handle encoding and decoding involving unicode characters annd going back and forth from ascii
我正在研究讀取xls文件(MHTML格式)的程序(Python 2.7)。 我遇到的一個問題是文件包含不是ascii的符號/字符。 我最初的解決方案是使用unicode讀取文件
這是我在文件中閱讀的方式:
theString=unicode(open(excelFile).read(),'UTF-8','replace')
然后我使用lxml進行一些處理。 這些文件有很多表,我處理的第一步要求我找到合適的表。 我可以根據第一行第一個單元格中的單詞找到該表。 這是變得棘手的地方。 我本來希望使用正則表達式來測試單元格的text_content(),但發現單詞的變體太多了(在3,200個文件的測試運行中,我發現91種不同的方式,這個概念只定義了其中一個因此我決定將特定單元格的所有text_contents轉儲出去,並使用excel中的一些算法來嚴格識別所有變體。
我用來編寫text_content()的代碼是
headerDict['header_'+str(column+1)]=encode(string,'Latin-1','replace')
我這樣做基於以前類似於我的問題的答案,似乎共識是使用unicode讀取文件然后在文件寫出之前對其進行編碼。
所以我處理了excel中的標簽/單詞 - 將它們全部轉換為小寫並刪除空格並將輸出保存為文本文件。
文本文件中有一列列出了我要查找的表的所有獨特方式
然后,我正在閱讀文件 - 我第一次使用時閱讀了它
labels=set([label for label in unicode(open('C:\\balsheetstrings-1.txt').read(),'UTF-8','replace').split('\n')])
我運行我的程序並發現一些匹配沒有發生,調查它我發現unicode用\\ ufffd替換某些charactors,如下例所示
u'unauditedcondensedstatementsoffinancialcondition(usd\ufffd$)inthousands'
更多的研究表明,當unicode沒有字符映射時(或許不是確切的解釋,但這是我的解釋),更換發生了。
所以,我嘗試(在考慮我必須失去什么之后)在不使用unicode的標簽列表中閱讀。 所以我在使用這段代碼時讀到了它:
labels=set(open('C:\\balsheetstrings-1.txt').readlines())
現在在看口譯員時看到的是同一個標簽
'unauditedcondensedstatementsoffinancialcondition(usd\xa0$)inthousands'
然后,我嘗試使用這組標簽進行匹配,但出現此錯誤
Warning (from warnings module):
File "C:\FunctionsForExcel.py", line 128
if tableHeader in testSet:
UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
現在令人沮喪的是tableHeader的值不在測試集中當我在tableHeader打破之后詢問它的值時我收到了這個
'fairvaluemeasurements:'
當我把測試輸入空閑時,加上侮辱傷害
tableHeader in testSet
它正確地返回false
我知道代碼'\\ xa0'是不間斷空格的代碼。 當我在不使用unicode的情況下讀取它時,Python也是如此。 我以為我已經擺脫了excel中的所有空格但是要處理這些空間我將它們分開然后加入它們
labels=[''.joiin([word for word in label.split()] for label in labels])
我還沒有回答一個問題。 對不起,我仍然試圖解決這個問題。 在我看來,我在這里處理不一致的行為。 當我讀取最初的字符串並使用unicode和UTF-8時,如果你願意的話,所有字符都是perserved / transportable。 我將它們編碼為寫出來,並且它們在Excel中顯示正常,然后我將它們保存為txt文件,它們看起來沒問題但是有些事情正在發生,我似乎無法弄清楚在哪里。
如果我可以避免寫出字符串來識別正確的標簽我覺得我的問題會消失,但有20,000或更多的標簽。 我可以使用正則表達式大大減少我的潛在列表,但其中一些僅需要檢查。
順便說一句,我將注意到源文件都指定了charset ='UTF-8'
回顧一下,當我使用unicode讀取sourcedocument和標簽列表時,我無法進行一些匹配,因為標簽中有一些字符被ufffd替換,當我在使用unicode和標簽列表中讀取sourcedocument時沒有任何特殊處理我得到警告。
我想了解發生了什么,所以我可以解決它,但我已經筋疲力盡了我能想到的所有地方
import codecs
# read a utf8 encoded file and return the data as unicode
data = codecs.open(excelFile, 'rb', 'UTF-8').read()
只要您在unicode中進行所有比較,您使用的編碼就無關緊要了。
我知道代碼'\\ xa0'是不間斷空格的代碼。
在字節字符串中, \\xA0
是一個字節,代表幾個編碼中的不間斷空格; 最有可能的是Windows代碼頁1252(西歐)。 但肯定不是UTF-8,其中byte \\xA0
本身無效。
使用.decode('cp1252')
將該字節字符串轉換為Unicode而不是'utf-8'
。 通常,如果您想知道HTML文件的編碼,請在<meta http-equiv="Content-Type">
標記中查找charset參數; 根據導出內容的不同,它可能會有所不同。
不完全是一個解決方案,但像xlrd這樣的東西可能比跳過所有這些籃球更有意義。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.