3

自分で作成したプログラムに一般的なファイルを読み込むのに問題があります。私が現在抱えている問題は、PDFが、私の操作全体にレンチを投げ込むBOMを含むある種の変異したutf-8に基づいていることです。私のアプリケーションでは、ASCII入力を必要とするSnowballステミングアルゴリズムを使用しています。utf-8に向けてエラーを解決することに関するトピックは多数ありますが、Snowballアルゴリズムにエラーを送信することや、ASCIIが最終結果になりたいという事実を考慮することはありません。現在使用しているファイルは、標準のANSIエンコーディングを使用したメモ帳ファイルです。私が受け取る特定のエラーメッセージはこれです:

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)

私の理解では、Python内では、ignore引数を含めると、検出されたASCII以外の文字が渡されるだけであり、このようにしてBOMや特殊文字をバイパスしますが、明らかにそうではありません。呼び出される実際のコードは次のとおりです。

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エンコーディングは機能しますが、私のアプリケーションには非常に理想的ではありません。自動化された方法でこれを修正する方法についてのアイデアはありますか?

Elementの初期デコードは失敗しますが、実際にエンコーダーに渡されると、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 

この型キャストのハックアラウンドは実際には機能しますが、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
4

1 に答える 1

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バイトが文字であるとは限らないため、これにより問題が発生する可能性があります(一部の文字はエンコードに数バイトかかります)。任意の文字列をasとbsのシーケンスに変換するエンコーディングを想像してみてください。aエンコードされていない文字列にsとsがない場合でも、どこにでもsと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にエンコードすることをお勧めします。

于 2012-06-06T14:58:03.520 に答える