2014年8月7日木曜日

pythonでnkfを使って文字コードの変換を行う要点だけ

環境依存文字を含むutf-8文字列をeuc_jpに変換したいときに、pythonのunicode.encode('euc_jp')だとエラーになってしまうのでこれをnkfモジュールで解決するという内容。


エラーは具体的には以下のような感じ
>>> unicode_str = unicode(u'①②③')
>>> print unicode_str
①②③
>>> unicode_str.encode('euc-jp')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'euc_jp' codec can't encode character u'\u2460' in position 0: illegal multibyte sequence 
環境依存文字の変換にはpythonのnkfモジュールを使うと良いと聞いたので試してみた。まずは必要なnkfコマンドとpython用のモジュールのインストール。ちなみにOSX MavericksとPython 2.7.7の環境で試した。
$ brew install nkf
$ pip install nkf
【追記】 深く考えずにnkfコマンドをHomebrewからインストールしたけどこれは不要かもしれない。

Pythonを起動してutfの文字列を読み込む。ファイルには「①②③」という文字列が入っている。今回はmiでファイルを開いて確認する。

ファイルから読み込んだ時点ではstr型。
$ python
Python 2.7.7 (default, Jun 14 2014, 23:12:13)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import nkf
>>> f = open('utf_orig.txt','r')
>>> str_utf = f.read()
>>> f.close()
>>> print str_utf
①②③
>>> type(str_utf)
<type 'str'>
比較用にunicodeオブジェクトも作成しておく。以下のような感じ
>>> str_uni = unicode(str_utf, 'utf-8')
>>> type(str_uni)
<type 'unicode'> 
nkfにはstringオブジェクトを渡すようなので、上記の例ではstr_utf(ファイルから読み込んだそのまま)を使う。第一引数にはnkfコマンドのオプション、第二引数に変換したいstr型のデータを渡す。今回はeuc_jpに変換したいので以下のようにする。

>>> str_euc = nkf.nkf('e', str_utf)
ファイルに書き出してみる
>>> fout = open('euc_converted.txt', 'w')
>>> fout.write(str_euc)
>>> fout.close() 
変更後の書き出したファイルを再びmiで開いてみると、今度はeuc_jpで環境依存文字が出力されていることが分かる。

では、unicodeオブジェクトがある場合にはどうするか?unicodeオブジェクトをいちど任意の文字コードでencodeしてstrオブジェクトにいったん戻して、その上でnkfメソッドを通せば良い。
>>> str = str_uni.encode('utf8')
>>> str_euc = nkf.nkf('e', str)

0 件のコメント:

コメントを投稿