Pythonで機種依存文字を含む文字列を半角から全角へ
March 03, 2009 at 11:40 PM | View Comments<追記 3/5>
hideakiさんのコメントとnullpobugさんの指摘どおり
Windowsでの文字コード変換 - 偏った言語信者の垂れ流し
cp932でオッケーでした。
>>> s = "コンゲツ えおⅡ"
>>> unicode(s, "cp932")
u'\uff7a\uff9d\uff79\uff9e\uff82 \u3048\u304a\u2161'
>>> print unicode(s, "cp932")
コンゲツ えおⅡ
cp932は試してたのですが、自分のipythonは文字コードがUTF8になるのを忘れてました(でも表示はsjis) 。
>>> s.decode("cp932")
---------------------------------------------------------------------------
exceptions.UnicodeDecodeError Traceback (most recent call last)
UnicodeDecodeError: 'cp932' codec can't decode bytes in position 0-1: illegal multibyte sequence
>>> s.decode("utf8")
u'\uff7a\uff9d\uff79\uff9e\uff82 \u3048\u304a\u2161'
よく原因を考えずに「あ、cp932だめじゃん」と思ってしまいました。
まぁ、nfkは他にもguessという素敵関数があるので、あれば便利
>>> import nkf
>>> nkf.guess(s)
'UTF-8'
>>> print s
・コ・晢スケ・橸セ・縺医♀竇。
>>> print nkf.nkf("-sx", s) #s はsjis xは半角→全角変換をしない
コンゲツ えおⅡ
>>> print unicode(s, "utf8").encode("cp932")
コンゲツ えおⅡ
hideakiさん、nullpobugさんありがとうございました。
<追記おしまい>
Windows & Shift_JISの話です。
Pythonで全角、半角文字の変換をするには昔からSetomitsさんが作ったzenhan.pyというのを使っているのですが、
このモジュールは文字をunicodeで渡さないといけない。
ところが、Windowsにはローマ数字(Ⅱ)のような機種依存文字というのがあって、それが含まれていると
>>> s = "コンゲツ えおⅡ"
>>> unicode(s, "sjis")
UnicodeDecodeError: 'shift_jis' codec can't decode bytes in position 8-9: illegal multibyte sequence
のようになってunicode文字列に変換できなくて困ってしまうことになります。
nkfならその辺の機種依存文字を上手く扱ってくれるのでNKF_pythonを使うことにしました。
インストールが面倒かなと思ったのですが、
そこでNKF_pythonをdllで公開してくれている方がいたのであり難く使わせてもらうことに!
python2.4から2.6までのdllを公開してくれています。
以下のような関数を作っておいて
def conv(string):
a = nkf.nkf("-w", string) #文字列をutf8で開く
b = unicode(a, "utf8")
c = zenhan.h2z(b)
return nkf.nkf("-sX", c.encode("utf8")) #unicodeをutf8にエンコードした文字列をnkfでsjisへ変換
さきほどの文字列を変換すると
>>> print conv(s)
コンゲツ えおⅡ
ばっちり全角に変換できました。
conv関数が変数をたくさん使っているのはどこで止まったかはっきりさせるためなので、実際には、もっとすっきり書いたほうが良いでしょう。
categories:
python
ツイート