テキストファイルで使用されている文字コードを目視で確認する
呼称: 文字コード指定によるファイルオープン
目的: テキストファイルで使用されている文字コードを判別する
特徴: Python がサポートしている文字コードを全て試せる
用例: テキストファイルがどの文字コードを使用しているか分からないときに使用する
備考: 例外処理が冗長なのは python2.4 以下の互換性対応
最も精度の高い文字コードの判別処理を実装してみました(^ ^;;
対象とするテキストファイルの特性を考慮して read_line_num や supprt_charset を変更すると良いです。バッチ系の処理では、文字コード判別ライブラリを使用すると思いますが、それでは正常に判別できなかったファイルに対してのリカバリ処理で有用かなと思います。EUC-JP と EUC-CN 等は(テキストが少ないと)自動判別が難しいそうです。
#!/usr/bin/env python # -*- coding: utf-8 -*- import codecs import os import sys read_line_num = 5 support_charset = [ 'shift_jis', 'euc_jp', 'iso2022_jp', 'utf-8', 'iso8859_1', 'iso8859_5', 'iso8859_9', 'koi8_r', 'koi8_u', 'gb18030', 'euc_kr', 'big5', ] class Null(object): """NULL オブジェクト""" def __new__(cls, *args, **kwargs): # Singleton for 1 instance if '_inst' not in vars(cls): cls._inst = super(Null, cls).__new__(cls, *args, **kwargs) return cls._inst def __init__(self, *args, **kwargs): pass def __call__(self, *args, **kwargs): return self def __repr__(self): return 'Null()' def __iter__(self): return iter(()) def __nonzero__(self): return False def __getattr__(self, name): return self def __setattr__(self, name): return self def __delattr__(self, name): return self def main(): """Script Main""" target_file = sys.argv[1:] for file in target_file: content = get_content_with_various_charset(file) print '*'*10, file, '*'*10 for key, value in content.items(): print key, value def open_file(file, charset): """ファイルをオープンしてファイル識別子を返す 失敗したときは Null オブジェクトを返す """ fp = Null() if os.access(file, os.R_OK): try: fp = codecs.open(file, encoding=charset, mode='r') except IOError, err: pass return fp def get_content_with_various_charset(file): """対応文字コードを指定してファイルを開いて 最初の数行のテキストを返す""" text, content = '', {} for charset in support_charset: text, line_num = '', 0 fp = open_file(file, charset) try: try: for line in fp: line_num +=1 text += line if line_num == read_line_num: break content[charset] = text except Exception, err: pass finally: fp.close() return content if __name__ == '__main__': main()
実行結果。
$ python open_with_various_charset.py sjis.txt eucjp.txt utf8.txt ********** sjis.txt ********** gb18030 丂丂戞擇栭 丂偙傫側柌傪尒偨丅 丂榓彯偺幒傪戅偑偭祹丄楲壓揱偄偵帺暘偺晹壆傊婣傞偲峴摂偑傏傫傗傝揰偭祹偄傞丅 曅旼傪嵗姉抍偺忋偵撍偄祹丄摂怱傪憕偒棫祹偨偲偒丄壴偺傛祥側挌巕偑傁偨傝偲 koi8_r │@│@▒Ф⌠Я√И │@┌╠┌Я┌х√╡┌П▄╘┌╫│B │@≤a▐╝┌л▌╨┌П▒ч┌╙┌а┌д│A≤L┴╨⌠`┌╒┌и▌╘∙╙┌л∙■┴╝┌ж▀A┌И┌ф█s⌠■┌╙┌з┌Я┌Б┌Х⌠_┌а┌д┌╒┌И│B ∙п∙G┌П█ю┼≈▓c┌л▐Ц┌и⌠к┌╒┌д│A⌠■░S┌П▒~┌╚≈╖┌д┌╫┌ф┌╚│A┴т┌л┌Ф┌╓┌х▓ ▌q┌╙┌о┌╫┌Х┌ф shift_jis 第二夜 こんな夢を見た。 和尚の室を退がって、廊下伝いに自分の部屋へ帰ると行灯がぼんやり点っている。 片膝を座蒲団の上に突いて、灯心を掻き立てたとき、花のような丁子がぱたりと iso8859_9 @@æñé @±ñȲğ©½B @a®ÌºğުÁÄALº`¢É©ªÌ®ÖAéÆsªÚñâè_ÁÄ¢éB ĞGğÀcÌãÉË¢ÄASğ~«§Ä½Æ«AÔÌæ¤ÈqªÏ½èÆ koi8_u │@│@▒Ф⌠Я√И │@┌╠┌Я┌х√╡┌П▄╘┌Ґ│B │@≤a▐╝┌л▌╨┌П▒ч┌╙┌а┌д│A≤L┴╨⌠`┌╒┌и▌╘∙╙┌л∙■┴╝┌ж▀A┌И┌ф█s⌠■┌╙┌з┌Я┌Б┌Х⌠_┌а┌д┌╒┌И│B ∙п∙G┌П█ю┼≈▓c┌л▐Ц┌и⌠к┌╒┌д│A⌠■░S┌П▒~┌╚≈ї┌д┌Ґ┌ф┌╚│A┴т┌л┌Ф┌є┌х▓ ▌q┌╙┌о┌Ґ┌Х┌ф iso8859_5 @@цёщ @БёШВ№ЉНB @aЎЬК№оЊСФALК`ЂЩЉЊЬЎжAщЦsЊкётш_СФЂщB аG№РcЬуЩЫЂФAS№~ЋЇФНЦЋAдЬцЄШqЊЯНшЦ iso8859_1 @@æñé @±ñȲð©½B @a®ÌºðÞªÁÄALº`¢É©ªÌ®ÖAéÆsªÚñâè_ÁÄ¢éB ÐGðÀcÌãÉË¢ÄASð~«§Ä½Æ«AÔÌæ¤ÈqªÏ½èÆ ********** eucjp.txt ********** koi8_r ║║║║бХ╩╟лК ║║╓Ё╓С╓йл╢╓Р╦╚╓©║ё ║║о╩╓д╓к╓й╓К╩р╤║╓РиИ╓ц╓ф╓К║ё╓©╓╥╓╚╓к╪╚й╛╓н╩р╓г╓╒╓К║ё╓©╓юит╩в╣д╓й╩Ж╓к╓о ╓╓╓д╓н╢ж╓к╓╚╢Ц╓╛ды╓Л╓ф║╒юдк╥╪Г╓к╓й╓ц╓ф╓╓╓К║ё╪╚й╛╓╛╦Фа╟╓н╢Ц╓о╓╓╓дды╓Л╓©╓н╓╚╓╓ gb18030 妈话屉 こんな檀を斧た。 匣つになる灰丁を砷ってる。たしかに极尸の灰である。ただ稍蛔的な祸には いつの粗にか淬が馁れて、滥朔肩になっている。极尸が告涟の淬はいつ馁れたのかい big5 ﹛﹛鎔趕歾 ﹛仇氏卅抴毛葦凶﹝ ﹛牰勾卞卅月閡間毛扙勻化月﹝凶仄井卞憤坌及閡匹丐月﹝凶分尕閤腔卅儀卞反 中勾及棉卞井氬互囁木化﹜斂侇潛卞卅勻化中月﹝憤坌互豢蟆及氬反中勾囁木凶及井中 euc_jp 第三夜 こんな夢を見た。 六つになる子供を負ってる。たしかに自分の子である。ただ不思議な事には いつの間にか眼が潰れて、青坊主になっている。自分が御前の眼はいつ潰れたのかい iso8859_9 ¡¡¡¡Âè»°Ìë ¡¡¤³¤ó¤ÊÌ´¤ò¸«¤¿¡£ ¡¡Ï»¤Ä¤Ë¤Ê¤ë»Ò¶¡¤òÉé¤Ã¤Æ¤ë¡£¤¿¤·¤«¤Ë¼«Ê¬¤Î»Ò¤Ç¤¢¤ë¡£¤¿¤ÀÉԻ׵Ĥʻö¤Ë¤Ï ¤¤¤Ä¤Î´Ö¤Ë¤«´ã¤¬ÄÙ¤ì¤Æ¡¢ÀÄË·¼ç¤Ë¤Ê¤Ã¤Æ¤¤¤ë¡£¼«Ê¬¤¬¸æÁ°¤Î´ã¤Ï¤¤¤ÄÄ٤줿¤Î¤«¤¤ koi8_u ║║║║бХ╩╟лК ║║єЁєСєйлЄєР╦╚є©║ё ║║о╩єдєкєйєК╩рІ║єРиИєцєфєК║ёє©єЇє╚єк╪╚й╛єн╩рєгє╒єК║ёє©єюит╩в╣дєй╩Жєкєо єєєдєнЄжєкє╚ЄЦє╛дыєЛєф║╒юдкЇ╪ГєкєйєцєфєєєК║ё╪╚й╛є╛╦Фа╟єнЄЦєоєєєддыєЛє©єнє╚єє iso8859_5 ЁЁЁЁТшЛАЬы ЁЁЄГЄѓЄЪЬДЄђИЋЄПЁЃ ЁЁЯЛЄФЄЫЄЪЄыЛвЖЁЄђЩщЄУЄЦЄыЁЃЄПЄЗЄЋЄЫМЋЪЌЄЮЛвЄЧЄЂЄыЁЃЄПЄРЩдЛзЕФЄЪЛіЄЫЄЯ ЄЄЄФЄЮДжЄЫЄЋДуЄЌФйЄьЄЦЁЂРФЫЗМчЄЫЄЪЄУЄЦЄЄЄыЁЃМЋЪЌЄЌИцСАЄЮДуЄЯЄЄЄФФйЄьЄПЄЮЄЋЄЄ iso8859_1 ¡¡¡¡Âè»°Ìë ¡¡¤³¤ó¤ÊÌ´¤ò¸«¤¿¡£ ¡¡Ï»¤Ä¤Ë¤Ê¤ë»Ò¶¡¤òÉé¤Ã¤Æ¤ë¡£¤¿¤·¤«¤Ë¼«Ê¬¤Î»Ò¤Ç¤¢¤ë¡£¤¿¤ÀÉԻ׵Ĥʻö¤Ë¤Ï ¤¤¤Ä¤Î´Ö¤Ë¤«´ã¤¬ÄÙ¤ì¤Æ¡¢ÀÄË·¼ç¤Ë¤Ê¤Ã¤Æ¤¤¤ë¡£¼«Ê¬¤¬¸æÁ°¤Î´ã¤Ï¤¤¤ÄÄ٤줿¤Î¤«¤¤ ********** utf8.txt ********** koi8_r Ц──Ц──Г╛╛Е⌡⌡Е╓° Ц──Е╨┐Ц│└Е°÷И√⌠Ц│╝Г°÷Д╦╜Ц│╚Ф╤╪Ц│©Е▐╟Ц│╝Ц┌┬Ц│├Ц│╙Ц┌┌Ц│╝Ц┌▓Ф█╝Ц│┬Ц│╕Ц─│Ц│²Ц│╝Е▒╗Е⌡╡Ц│╚Е╟▐Ц│∙Ц│└Е╨┼Е┤═Ц│▄Д╦╕Ц│╧Ц│╕Ц│┌Ц┌▀Ц─┌ Е▐╟Ц│╞И╩▓Е┘┴Ц┌┼Ц│╚Е┘┴Ц│ёЦ│╕Ц│└Ц┌▀Ц─┌Г┴┤И ┘Ц│╚Ц│╞Е⌡⌡Х╖▓Ц│╙Х├ЁЦ┌▓Е┴█Ц│╚Г╫╝Ц│└Ц│╕Г┬╨Ц│∙Ц┌⌠Ц│▄Д╦─Д╨╨Ц│╖И┘▓Ц┌▓Иё╡Ц┌⌠Ц│╖Ц│└Ц┌▀Ц─┌ Х┌╢Ц│╞Г┘╝Ц│≈Ц┌│Ц┌┴Ц│≈Ц│└Ц─┌ iso8859_9 ãã第åå¤ ãåºãåéã®çä¸ã«æ¶¼ã¿å°ã®ãããªãã®ãæ®ãã¦ããã®å¨å²ã«å°ããåºå ã並ã¹ã¦ããã å°ã¯é»å ãã«å utf-8 第四夜 広い土間の真中に涼み台のようなものを据えて、その周囲に小さい床几が並べてある。 台は黒光りに光っている。片隅には四角な膳を前に置いて爺さんが一人で酒を飲んでいる。 肴は煮しめらしい。 koi8_u Ц──Ц──Г╛╛Е⌡⌡Еє° Ц──Е╨┐Ц│└Е°÷И√⌠Ц│╝Г°÷Д╦ґЦ│╚ФІ╪Ц│©Е▐╟Ц│╝Ц┌┬Ц│├Ц│╙Ц┌┌Ц│╝Ц┌▓Ф█╝Ц│┬Ц│іЦ─│Ц│²Ц│╝Е▒╗Е⌡╡Ц│╚Е╟▐Ц│∙Ц│└Е╨┼Е┤═Ц│▄Д╦іЦ│╧Ц│іЦ│┌Ц┌▀Ц─┌ Е▐╟Ц│╞И╩▓Е┘┴Ц┌┼Ц│╚Е┘┴Ц│ёЦ│іЦ│└Ц┌▀Ц─┌Г┴┤И ┘Ц│╚Ц│╞Е⌡⌡Хї▓Ц│╙Х├ЁЦ┌▓Е┴█Ц│╚ГҐ╝Ц│└Ц│іГ┬╨Ц│∙Ц┌⌠Ц│▄Д╦─Д╨╨Ц│їИ┘▓Ц┌▓Иё╡Ц┌⌠Ц│їЦ│└Ц┌▀Ц─┌ Х┌ЄЦ│╞Г┘╝Ц│≈Ц┌│Ц┌┴Ц│≈Ц│└Ц─┌ iso8859_5 уучЌЌххЄ ухКухщуЎчфИуЋцЖМуПхАуЎуууЊууЎуцЎууІуууЎхЈхВуЋхАуухКх уфИІуЙуІууу хАуЏщЛх ууЋх iso8859_1 ãã第åå¤ ãåºãåéã®çä¸ã«æ¶¼ã¿å°ã®ãããªãã®ãæ®ãã¦ããã®å¨å²ã«å°ããåºå ã並ã¹ã¦ããã å°ã¯é»å ãã«å
リファレンス:
http://www.python.jp/doc/release/lib/module-codecs.html
Python でUTF-8, shift_jis, euc_jpなど日本語を使う方法
Pythonの例外とその処理に関する覚え書き(概要、書式、後始末処理) - 試験運用中なLinux備忘録