1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

chardetの文字コード誤判定を回避する ― Pythonで安全な文字コード判定ロジックの実装

Posted at

はじめに

Pythonでテキストファイルを扱う際、文字コードの自動判定が必要になることがあります。
多くのエンジニアが頼るのが chardetnkf ライブラリ化と思いますが、必ずしも完璧ではありません。

実際にきょう私は業務で、chardetを使っていて、Shift_JISのテキストファイルがWindows-1252と誤判定されるという事象に直面しました。
本記事では、その問題の再現と、業務で採用した安全な文字コード判定ロジックをご紹介します。

問題の発端:Shift_JISがWindows-1252と誤判定される

import chardet

with open("sample_sjis.txt", "rb") as f:
    raw_data = f.read()
    result = chardet.detect(raw_data)

print(result)

出力例

{'encoding': 'Windows-1252', 'confidence': 0.73, 'language': ''}

Shift_JISファイルなのに、Windows-1252 と判定されました。

なぜ誤判定が起きるのか?

  • Shift_JISとWindows-1252のバイト表現が一部似ている
  • chardet は統計的推定に基づいており、誤差が避けられない
  • 英数字中心の日本語ファイルは特に誤判定されやすい

解決策:主要な文字コードを優先的に試す

chardet を最後の手段にして、一般的に使用が想定される主要なエンコーディングを先に順番に試みることで、安全性を確保します。

from pathlib import Path
import chardet

COMMON_ENCODINGS = ["utf-8", "shift_jis", "euc_jp", "iso2022_jp"]

def detect_encoding(filepath: Path) -> str:
    content = filepath.read_bytes()

    for enc in COMMON_ENCODINGS:
        try:
            content.decode(enc)
            return enc
        except UnicodeDecodeError:
            continue

    # 最終手段として chardet
    result = chardet.detect(content)
    return result["encoding"] or "utf-8"

# 使用例
file_path = Path("sample_sjis.txt")
detected = detect_encoding(file_path)
print(f"Detected encoding: {detected}")

まとめ

  • chardet は便利だが、誤判定のリスクがある
  • よく使われる文字コードを先に試すことで安全性を確保できる
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?