2013-09-02 2 views
5

私は、私がPythonやテキストエンコーディングをするよりも、自転車の修理、チェーンソーの使用、トレンチの安全性についてもっと知っています。私が読んだSearching text files' contents with various encodings with Python?、その他::このことを念頭に置いて...Pythonでテキストファイルのエンコーディングを検出するためのコードに落とし穴がありますか?

Pythonのテキストエンコーディングは、多年生の問題(自分の質問のようです。12を私が推測するいくつかのコードを書くことで亀裂を撮影しました以下のエンコーディング。

限られたテストでは、このコードは、私は、これらのデータは有益でないテキストエンコーディングの最初の3つのバイトや状況についての過剰を知らなくても、私の目的*のために働くようだ。

*私の目的は:

  1. 私は中程度の成功率で使用できる依存関係のないスニペットを持っています
  2. エンコードされたテキストベースのログファイルをローカルワークステーションでスキャンし、その内容に基づいて興味を持っていますファイルを適切なエンコーディングで開く必要があります)
  3. この問題を解決するには、

質問:私は以下のように行うの文字を比較し、カウントklutzy方法であると仮定ものを使用しての落とし穴とは何ですか?どんな入力も大歓迎です。

def guess_encoding_debug(file_path): 
    """ 
    DEBUG - returns many 2 value tuples 
    Will return list of all possible text encodings with a count of the number of chars 
    read that are common characters, which might be a symptom of success. 
    SEE warnings in sister function 
    """ 

    import codecs 
    import string 
    from operator import itemgetter 

    READ_LEN = 1000 
    ENCODINGS = ['ascii','cp1252','mac_roman','utf_8','utf_16','utf_16_le',\ 
       'utf_16_be','utf_32','utf_32_le','utf_32_be'] 

    #chars in the regular ascii printable set are BY FAR the most common 
    #in most files written in English, so their presence suggests the file 
    #was decoded correctly. 
    nonsuspect_chars = string.printable 

    #to be a list of 2 value tuples 
    results = [] 

    for e in ENCODINGS: 
     #some encodings will cause an exception with an incompatible file, 
     #they are invalid encoding, so use try to exclude them from results[] 
     try: 
      with codecs.open(file_path, 'r', e) as f: 

       #sample from the beginning of the file 
       data = f.read(READ_LEN) 

       nonsuspect_sum = 0 

       #count the number of printable ascii chars in the 
       #READ_LEN sized sample of the file 
       for n in nonsuspect_chars: 
        nonsuspect_sum += data.count(n) 

       #if there are more chars than READ_LEN 
       #the encoding is wrong and bloating the data 
       if nonsuspect_sum <= READ_LEN: 
        results.append([e, nonsuspect_sum]) 
     except: 
      pass 

    #sort results descending based on nonsuspect_sum portion of 
    #tuple (itemgetter index 1). 
    results = sorted(results, key=itemgetter(1), reverse=True) 

    return results 


def guess_encoding(file_path): 
    """ 
    Stupid, simple, slow, brute and yet slightly accurate text file encoding guessing. 
    Will return one likely text encoding, though there may be others just as likely. 
    WARNING: DO NOT use if your file uses any significant number of characters 
      outside the standard ASCII printable characters! 
    WARNING: DO NOT use for critical applications, this code will fail you. 
    """ 

    results = guess_encoding_debug(file_path) 

    #return the encoding string (second 0 index) from the first 
    #result in descending list of encodings (first 0 index) 
    return results[0][0] 

私はそれは私がして、特に慣れていないよchardetに比べて遅くなると仮定しています。また、あまり正確ではない。彼らはそれが設計されているように、アクセント、ウムラウトなどを使用するローマ字に基づく言語は、少なくともうまく動作しません。それがいつ失敗するかは分かりません。しかし、ほとんどのプログラミングコードを含むほとんどのテキストは、このコードが依存するstring.printableで大きく記述されます。

外部ライブラリは、将来の選択肢かもしれないが、今のところ、私はので、それらを避けるためにしたい:このスクリプトは、Pythonのさまざまなバージョンとネットワークのオンとオフの複数の会社のコンピュータ上で実行されます

  1. 、合併症が少ないほど良い。私が「会社」と言うとき、私は社会科学者の小さな非営利を意味します。
  2. 私はGPSデータ処理からログを収集していますが、私はシステム管理者ではありません。彼女はPythonプログラマーではなく、私が彼女のほうが良いと感じる時間が少なくなっています。
  3. 私の会社で一般的に入手可能なPythonのインストールは、GISソフトウェアパッケージと共にインストールされ、放置された方が一般的に優れています。
  4. 私の要件はあまり厳しくありません。興味のあるファイルを特定し、他の方法でアーカイブにコピーしたいだけです。私は、コンテンツを操作、追加、または書き換えるために、全内容をメモリに読み込んでいません。
  5. これは、高度なプログラミング言語のように、これを単独で達成するための何らかの方法が必要です。 「みたいに思える」という言葉は、あらゆる努力のための不安な基盤ですが、私はそれを働かせることができるかどうか試してみたかったのです。
+0

よく書かれた質問のために+1!よく研究され、よく書かれた例もあります。 –

+1

既存のライブラリを使用しない理由は何ですか? chardetやchared(https://code.google.com/p/chared/)のように? – amit

+0

私が知っていることから、あなたが挙げたもののような、この種のライブラリには非常に良いライブラリがいくつかあります。私は彼らが私が思いつくことができるより強力であると確信しているので、それらを使用する方法を学ぶ時間を持つことを望む。しかし、外部ライブラリを避ける理由はたくさんあります。私は私の理由をより良く述べるために投稿を編集しました。 –

答えて

0

おそらくコードがうまく動作するかを調べる最も簡単な方法は、他の既存のライブラリのテストスイートを使用して、それらをベースとして使用して独自の包括的なテストスイートを作成することです。彼らはあなたのコードがこれらすべてのケースで動作するかどうかを知っていますし、気になるケースについてもテストすることができます。

関連する問題