2012-06-06 37 views
3

我在將一般文件讀入我編寫的程序時遇到了一些麻煩。我目前遇到的問題是pdf基於某種突變的utf-8,其中包含一個BOM,它會在我的整個操作中引發一個扳機。在我的應用程序中,我使用了需要ASCII輸入的雪球干擾算法。有一些話題涉及到向utf-8解決錯誤的問題,但是他們都不涉及將它們發送到Snowball算法,或者考慮ascii是我想要的最終結果。目前我使用的文件是使用標準ANSI編碼的記事本文件。特定的錯誤消息我得到的是這樣的:UnicodeDecodeError,ascii處理python中的Snowball干擾算法

File "C:\Users\svictoroff\Desktop\Alleyoop\Python_Scripts\Keywords.py", line 38, in Map_Sentence_To_Keywords 
    Word = Word.encode('ascii', 'ignore') 
UnicodeDecodeError: 'ascii' codec can't decode byte 0x96 in position 0: ordinal not in range(128) 

我的理解是蟒蛇內,包括忽略的說法只會越過遇到並以這種方式我會繞過任何BOM或特殊字符的任何非ASCII字符,但顯然情況並非如此。所謂實際的代碼是在這裏:

def Map_Sentence_To_Keywords(Sentence, Keywords): 
    '''Takes in a sentence and a list of Keywords, returns a tuple where the 
    first element is the sentence, and the second element is a set of 
    all keywords appearing in the sentence. Uses Snowball algorithm''' 
    Equivalence = stem.SnowballStemmer('english') 
    Found = [] 
    Sentence = re.sub(r'^(\W*?)(.*)(\n?)$', r'\2', Sentence) 
    Words = Sentence.split() 
    for Word in Words: 
     Word = Word.lower().strip() 
     Word = Word.encode('ascii', 'ignore') 
     Word = Equivalence.stem(Word) 
     Found.append(Word) 
    return (Sentence, Found) 

通過包括普通非貪婪非字符正則表達式遣返我也希望麻煩字符將被刪除字符串的前面,但這又並非如此。除了ascii之外,我還嘗試了一些其他編碼,並且嚴格的base64編碼工作,但對於我的應用程序來說非常不理想。有關如何以自動方式解決此問題的任何想法?

元素的初始解碼失敗,但實際傳遞給編碼器時返回unicode錯誤。

for Element in Curriculum_Elements: 
     try: 
      Element = Element.decode('utf-8-sig') 
     except: 
      print Element 
     Curriculum_Tuples.append(Map_Sentence_To_Keywords(Element, Keywords)) 

def scraping(File): 
    '''Takes in txt file of curriculum, removes all newlines and returns that occur \ 
    after a lowercase character, then splits at all remaining newlines''' 
    Curriculum_Elements = [] 
    Document = open(File, 'rb').read() 
    Document = re.sub(r'(?<=[a-zA-Z,])\r?\n', ' ', Document) 
    Curriculum_Elements = Document.split('\r\n') 
    return Curriculum_Elements 

顯示的代碼生成看到的課程元素。

for Element in Curriculum_Elements: 
     try: 
      Element = unicode(Element, 'utf-8-sig', 'ignore') 
     except: 
      print Element 

這種類型轉換hackaround實際上起作用,但隨後轉換回ascii有點笨拙。返回此錯誤:

Warning (from warnings module): 
    File "C:\Python27\lib\encodings\utf_8_sig.py", line 19 
    if input[:3] == codecs.BOM_UTF8: 
UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal 
+1

你確定它應該不貪心?假設你有''A^AHello,World!''。然後,由於非貪婪,在第一次捕獲中匹配''^ A''的** none **。他們最終在第二次捕獲,因此,在你的替代字符串。 –

+0

好點,但我的問題是真的只有在字符不能被識別的情況下。 –

回答

5

嘗試首先UTF-8輸入解碼成unicode字符串,則編碼成ASCII(忽略非ASCII)。編碼已編碼的字符串確實沒有意義。

input = file.read() # Replace with your file input code... 
input = input.decode('utf-8-sig') # '-sig' handles BOM 

# Now isinstance(input, unicode) is True 

# ... 
Sentence = Sentence.encode('ascii', 'ignore') 

的編輯後,我看到你已經嘗試在ASCII編碼之前對其進行字符串解碼。但是,在文件內容已經被操縱之後,解碼似乎已經太晚了。這可能會導致問題,因爲不是每個UTF-8字節都是一個字符(某些字符需要幾個字節才能編碼)。設想一種編碼,將任何字符串轉換爲a s和b s的序列。在解碼之前,你不想操縱它,因爲即使在未編碼的字符串中沒有任何字符串,你也會在任何地方都看到a s和b - UTF-8也出現了同樣的問題,儘管更爲巧妙, 大部分字節確實是字符。

因此,解碼一次,你做任何事情之前:

def scraping(File): 
    '''Takes in txt file of curriculum, removes all newlines and returns that occur \ 
    after a lowercase character, then splits at all remaining newlines''' 
    Curriculum_Elements = [] 
    Document = open(File, 'rb').read().decode('utf-8-sig') 
    Document = re.sub(r'(?<=[a-zA-Z,])\r?\n', ' ', Document) 
    Curriculum_Elements = Document.split('\r\n') 
    return Curriculum_Elements 

# ... 

for Element in Curriculum_Elements: 
    Curriculum_Tuples.append(Map_Sentence_To_Keywords(Element, Keywords)) 

你原來Map_Sentence_To_Keywords功能應不經修改,但我會分裂之前,建議編碼ASCII,只是爲了提高效率/可讀性。

+0

在傳遞給此函數之前,句子已被解碼。 –

+0

so句子是'unicode'的一個實例嗎?如果是這樣,你不應該得到這個錯誤。也許可以在函數的頂部添加一個'assert isinstance(Sentence,unicode)'來仔細檢查? – Cameron

+0

由於某些原因,解碼不起作用,將編輯以將相關代碼添加到此錯誤中。 –