Pythonで機種依存文字を含む文字列を半角から全角へ

  • March 03, 2009 23:40

<追記 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というのを使っているのですが、

blogSetomits : zenhan.py 0.4

このモジュールは文字を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関数が変数をたくさん使っているのはどこで止まったかはっきりさせるためなので、実際には、もっとすっきり書いたほうが良いでしょう。

Comments

March 04, 2009 15:13 by hideaki

エンコーディング名にsjisではなく、cp932を指定するのでは駄目なんですかね?

>>> unicode(s, "cp932")
u'\uff7a\uff9d\uff79\uff9e\uff82 \u3048\u304a\u2161'
>>> print unicode(s, "cp932")
コンゲツ えおⅡ

Windowsでかつ日本語環境のみで良ければmbcsでも
>>> unicode(s, "mbcs")
u'\uff7a\uff9d\uff79\uff9e\uff82 \u3048\u304a\u2161'
>>> print unicode(s, "mbcs")
コンゲツ えおⅡ

March 05, 2009 21:51 by uemura

hideakiさん

コメントありがとうございます。

その通りでした。本文も修正しました。