2010年05月05日

【Unicode】PythonでのUnicode下での半角カナと全角かな変換

 まあ、半角カナの濁点半濁点の用法に気を付けさえすれば簡単に作れるので探せば結構たくさんモジュールが見つかるテーマだが、Shift_JISやEUC-JPとのお付合いが長かったので、今のUnocode下での処理を確かめる意味で自己流で、半角カナを全角のカタカナやひらがなに変換する関数を書いて試た。

 作り方は、ここで挙げた辞書などの対応表を参照して、変換対象文字列より一文字ずつ参照し置換して行く方法以外に、replace()メソッドで全半角文字の字種数回分、変換対象文字を舐めまわし変換する方法もあるが、変換対象文字数×字種数の処理となるので非効率なので採用しなかった。勿論、辞書参照でも、変換対象文字数回分、辞書参照を行なうという回数面では変わらない単に、辞書という標準の仕組みの処理の速さに期待してのことだ。文字コード体系自体に着目して数式で処理する法が多分早いだろうが、当方が想定する変換用途としては、例えばカナ名のユーザ入力で半角カナがあったときに全角に変換してしまうとか、半角カナを含むものとそうでないものとの比較に使ったり、以前テスト用で使った郵便番号簿データの様に半角カナでの情報提供しかないものを変換または比較する程度なので、この辞書参照方式で充分かと思う。

 この辞書参照方式の場合、半角の「゛」・「゜」といった濁点・半濁点は、その直前の文字付けて処理の判断をしなければならない。今回はその細かいところを簡単に処理する為に、予め文字列を反転させ、お尻の文字から順次処理、濁点れ半濁点に当たったら、次の文字次第で処理する方法を使ったが、文字列のreverse()メソッドの様なものがUnicodeオブジェクトには無い様なので、それもおまけで作ることになった。完全なテストではないが、テスト用のに使ったコードを_test()という関数にして添付しているが、その為に、Unicode昇順並替用sort()関数も付けた。その実行結果は以下の通り。



[root@l22dm ~]# python /usr/local/lib/python2.6/site-packages/mire/jpcode.py

test =
あいうえお、アイウエオ、
がぎくげご、ガギグゲゴ
ぱぴぷぺぼ、パピプペポ
バ゙ビ゙
ヴ


test =
あいうえお、あいうえお、
がぎくげご、がぎぐげご
ぱぴぷぺぼ、ぱぴぷぺぽ
ば゛び゛
う゛


test =
あいうえお、アイウエオ、
がぎくげご、ガギグゲゴ
ぱぴぷぺぼ、パピプペポ
バ゛ビ゛




チナノヘムユルンゾブギポデド「ヲェョゴイカコピビセツニハホメヨレ゙ボゲ。・ゥュアオケペベステヴヌヒマモラロダ゚ザプ、ゼィャジエクシガタバパトネフミヤリヅワズヂ」ァォウグキサソ
ちなのへむゆるんぞぶぎぽでど「をぇょごいかこぴびせつにはほめよれ゛ぼげ。・ぅゅあおおぺべすてう゛ぬひまもらろだ゜ざぷ、ぜぃゃじえくしがたばぱと ねふみやりづわずぢ」ぁぉうぐきさそ
チナノヘムユルンゾブギポデド「ヲェョゴイカコピビセツニハホメヨレ゛ボゲ。・ゥュアオケペベステヴヌヒマモラロダ゜ザプ、ゼィャジエクシガタバパトネ フミヤリヅワズヂ」ァォウグキサソ

、。「」ぁあぃいぅううぇえぉおおかがきぎくぐげこごさざしじすずせぜそぞただちぢつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃ やゅゆょよらりるれろわをん゛゛゜・
、。「」゛゜ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモ ャヤュユョヨラリルレロワヲンヴ・
[root@l22dm ~]#
 ご覧の通り、ひらがなにはカタカナにある「ヴ」がないという規格上いやらしい課題もある。従って、全角間でのひらがなカタカナ変換の関数を作ろうとする場合にはその処理を加味しなければならない。

 今回作った半角カナからの全角かな変換のソースコードは以下の通り。尚、当方では今後のテストの為、自分のmireモジュールにjpcodeを登録した。

2012-01-18追記: 大幅書き直し。【Unicode】PythonでのUnicode下での半角カナと全角かな変換(2)でご覧頂きたい。
2012-01-24追記: ※ ご利用は、「【Unicode】半角カナ全角かな置替関数 for Python(正式公開版)」に掲載している最新版のjpcode.pyを活用頂きたい。追記(2010-05-06):  このコードはもう古くなりました。下記の最新版を御覧下さい。
 /usr/local/lib/python2.6/site-packages/mire/jpcode.py


#!/usr/loca/bin/python2.6
# -*- coding: UTF8 -*-

u"""
######################################################################
# 1. reverse(s) : Unicode文字列用の降順並替
# 2. sort(s) : Unicode文字列用の昇順並替
# 3. kana2zen(s, : 半角カナの全角カナ変換
# mode : hira(既定)=全角ひらがなへ
# : その他 =全角カタカナへ
"""

__author__ = "Mire in Japan"
__version__ = '0.0.0'
__copyright__ = 'Copyright (c) 2010 Mire'
__license__ = 'GPL'
__url__ = 'http://pythonlife.seesaa.net/'

## 半角カナ⇒全角ひらがな辞書 ##
han2hira = { u'ア' :u'あ', u'イ' :u'い', u'ウ' :u'う', u'エ' :u'え', u'オ' :u'お'
, u'カ' :u'か', u'キ' :u'き', u'ク' :u'く', u'ケ' :u'', u'コ' :u'こ'
, u'サ' :u'さ', u'シ' :u'し', u'ス' :u'す', u'セ' :u'せ', u'ソ' :u'そ'
, u'タ' :u'た', u'チ' :u'ち', u'ツ' :u'つ', u'テ' :u'て', u'ト' :u'と'
, u'ナ' :u'な', u'ニ' :u'に', u'ヌ' :u'ぬ', u'ネ' :u'ね', u'ノ' :u'の'
, u'ハ' :u'は', u'ヒ' :u'ひ', u'フ' :u'ふ', u'ヘ' :u'へ', u'ホ' :u'ほ'
, u'マ' :u'ま', u'ミ' :u'み', u'ム' :u'む', u'メ' :u'め', u'モ' :u'も'
, u'ヤ' :u'や', u'ユ' :u'ゆ', u'ヨ' :u'よ', u'゚' :u'゜', u'゙' :u'゛'
, u'ラ' :u'ら', u'リ' :u'り', u'ル' :u'る', u'レ' :u'れ', u'ロ' :u'ろ'
, u'ワ' :u'わ', u'ン' :u'ん', u'「' :u'「', u'」' :u'」', u'。' :u'。'
, u'、' :u'、', u'・' :u'・', u'ァ' :u'ぁ', u'ィ' :u'ぃ', u'ゥ' :u'ぅ'
, u'ェ' :u'ぇ', u'ォ' :u'ぉ', u'ャ' :u'ゃ', u'ュ' :u'ゅ', u'ョ' :u'ょ'

, u'ガ':u'が', u'ギ':u'ぎ', u'グ':u'ぐ', u'ゲ':u'げ', u'ゴ':u'ご'
, u'ザ':u'ざ', u'ジ':u'じ', u'ズ':u'ず', u'ゼ':u'ぜ', u'ゾ':u'ぞ'
, u'ダ':u'だ', u'ヂ':u'ぢ', u'ヅ':u'づ', u'デ':u'で', u'ド':u'ど'
, u'バ':u'ば', u'ビ':u'び', u'ブ':u'ぶ', u'ベ':u'べ', u'ボ':u'ぼ'
, u'パ':u'ぱ', u'ピ':u'ぴ', u'プ':u'ぷ', u'ペ':u'ぺ', u'ポ':u'ぽ'
, u'ヲ':u'を'}

## 半角カナ⇒全角カタカナ辞書 ##
han2kata = { u'ア' :u'ア', u'イ' :u'イ', u'ウ' :u'ウ', u'エ' :u'エ', u'オ' :u'オ'
, u'カ' :u'カ', u'キ' :u'キ', u'ク' :u'ク', u'ケ' :u'ケ', u'コ' :u'コ'
, u'サ' :u'サ', u'シ' :u'シ', u'ス' :u'ス', u'セ' :u'セ', u'ソ' :u'ソ'
, u'タ' :u'タ', u'チ' :u'チ', u'ツ' :u'ツ', u'テ' :u'テ', u'ト' :u'ト'
, u'ナ' :u'ナ', u'ニ' :u'ニ', u'ヌ' :u'ヌ', u'ネ' :u'ネ', u'ノ' :u'ノ'
, u'ハ' :u'ハ', u'ヒ' :u'ヒ', u'フ' :u'フ', u'ヘ' :u'ヘ', u'ホ' :u'ホ'
, u'マ' :u'マ', u'ミ' :u'ミ', u'ム' :u'ム', u'メ' :u'メ', u'モ' :u'モ'
, u'ヤ' :u'ヤ', u'ユ' :u'ユ', u'ヨ' :u'ヨ', u'゚' :u'゜', u'゙' :u'゛'
, u'ラ' :u'ラ', u'リ' :u'リ', u'ル' :u'ル', u'レ' :u'レ', u'ロ' :u'ロ'
, u'ワ' :u'ワ', u'ン' :u'ン', u'「' :u'「', u'」' :u'」', u'。' :u'。'
, u'、' :u'、', u'・' :u'・', u'ァ' :u'ァ', u'ィ' :u'ィ', u'ゥ' :u'ゥ'
, u'ェ' :u'ェ', u'ォ' :u'ォ', u'ャ' :u'ャ', u'ュ' :u'ュ', u'ョ' :u'ョ'

, u'ガ':u'ガ', u'ギ':u'ギ', u'グ':u'グ', u'ゲ':u'ゲ', u'ゴ':u'ゴ'
, u'ザ':u'ザ', u'ジ':u'ジ', u'ズ':u'ズ', u'ゼ':u'ゼ', u'ゾ':u'ゾ'
, u'ダ':u'ダ', u'ヂ':u'ヂ', u'ヅ':u'ヅ', u'デ':u'デ', u'ド':u'ド'
, u'バ':u'バ', u'ビ':u'ビ', u'ブ':u'ブ', u'ベ':u'ベ', u'ボ':u'ボ'
, u'パ':u'パ', u'ピ':u'ピ', u'プ':u'プ', u'ペ':u'ペ', u'ポ':u'ポ'
, u'ヴ':u'ヴ'
, u'ヲ' :u'ヲ'}

def reverse(s):
"""
Unicode文字列用の降順並替
"""
st = u'%s' % (s)
r = []
for i in st: r.append(i)
r.reverse()
rs = u''
for i in r: rs = rs + i
return rs

def sort(s):
"""
Unicode文字列用の昇順並替
"""
st = u'%s' % (s)
r = []
for i in st: r.append(i)
r.sort()
rs = u''
for i in r: rs = rs + i
return rs

def kana2zen(s, mode='hira'):
u"""
半角カナの全角カナ変換
第一引数に変換対象文字列を指定。
mode='hira'(既定): ひらがなへ
それ以外なら カナカナへ
"""
## モード設定により辞書を選択 ##
if mode[0].upper() == 'H':
han2zen = han2hira
else:
han2zen = han2kata

## 処理用の文字列を作成 ##
o = u'%s' % (unicode(s)) # 濁音半濁音処理の為お尻から処理したいので
o = reverse(o) # Unicode文字として並びを反転した上で

## 処理用文字列で1文字ずつ処理 ##
z = p = '' # 処理用文字列の初期化
for h in o: # 1文字ずつ
if h in han2zen: # 半角カナの範囲EFBDA1-EFBE9Fの辞書にあるなら
if h == u'゙' or h == u'゚': # 濁点、半濁点なら
if p == u'゙' or p == u'゚': # ひとつ前もそうなら
z = z + han2zen[p] # 前のものを全角の濁点、半濁点に変換
p=h # 文字をpで記憶
else:
if h+p in han2zen: # 濁点、半濁点付の候補があれば
z = z + han2zen[h+p] # その文字に変換は
else: # そうでないなら、仕方ないので
z = z + han2zen[p] # 全角の濁点、半濁点に変換
z = z + han2zen[h] # 辞書で全角分に置換て文字列を作る
p = '' # 処理が済んだのでpの記憶を消去し通常モードに

else: # それ以外は
if not p == '': # pに記憶があるなら
z = z + han2zen[p] # その全角分を単独で登録
p = '' # 処理が済んだのでpの記憶を消去し通常モードに

z = z + h # そのままの文字を追加

## 全文字の処理が終わったら ##
return reverse(z) # 作成した文字列を文字単位で反転
# その変換した文字列を返す


def _test():
test = u"""
test =
あいうえお、アイウエオ、
がぎくげご、ガギグゲゴ
ぱぴぷぺぼ、パピプペポ
バ゙ビ゙
ヴ
"""
keys = han2kata.keys()
ks=''
for k in keys:
ks = ks + k
print test
print kana2zen(test)
print kana2zen(test, mode='kata')
print
print
print ks
print kana2zen(ks)
print kana2zen(ks, mode='kata')
print
print sort(kana2zen(ks))
print sort(kana2zen(ks, mode='kata'))

if __name__ == '__main__':
_test()
 尚、このコードは当方のUnicodeへの認識を高める目的なので、実務用途には、他の方が提供されているモジュールの利用をお勧めしておきます。というか、どれか一つを標準モジュール化出来るといいと思う。

 拙速な掲載で恐縮ながら、下記の様にコードを修正。半角カナへの逆変換も辞書切替で行なう仕組みで実現した他、登録辞書の修正やbebugモードの追加等を実施した。新しい_text()によるテスト実行結果と、そのソースコードは以下の通り。



[root@l22dm ~]# python /usr/local/lib/python2.6/site-packages/mire/jpcode.py
test orignal text

test =
全角平仮名:あいうえお、半角片仮名アイウエオ、
濁点平仮名:がぎくげご、濁点半角片仮名ガギグゲゴ
半濁平仮名:ぱぴぷぺぼ、半濁半角片仮名パピプペポ
濁点重複:バ゙ビ゙
ヴィー、ヴィー


半角カナを全角ひらがなへ
han2hira
カ⇒か ガ⇒が キ⇒き ギ⇒ぎ ク⇒く グ⇒ぐ ケ⇒ ゲ⇒げ コ⇒こ ゴ⇒ご

test =
全角平仮名:あいうえお、半角片仮名あいうえお、
濁点平仮名:がぎくげご、濁点半角片仮名がぎぐげご
半濁平仮名:ぱぴぷぺぼ、半濁半角片仮名ぱぴぷぺぽ
濁点重複:ば゛び゛
ヴィー、う゛ぃー


全角片仮名を全角平仮名へ
zkata2hira
オ⇒オ カ⇒カ ガ⇒ガ キ⇒キ ギ⇒ギ ク⇒ク グ⇒グ ケ⇒ケ ゲ⇒ゲ コ⇒コ

test =
全角平仮名:あいうえお、半角片仮名アイウエオ、
濁点平仮名:がぎくげご、濁点半角片仮名ガギグゲゴ
半濁平仮名:ぱぴぷぺぼ、半濁半角片仮名パピプペポ
濁点重複:バ゛ビ゛
ヴィー、ヴィー


全角ひらがなを全角カタカナへ
zhira2kata
オ⇒オ カ⇒カ ガ⇒ガ キ⇒キ ギ⇒ギ ク⇒ク グ⇒グ ケ⇒ケ ゲ⇒ゲ コ⇒コ

test =
全角平仮名:あいうえお、半角片仮名アイウエオ、
濁点平仮名:がぎくげご、濁点半角片仮名ガギグゲゴ
半濁平仮名:ぱぴぷぺぼ、半濁半角片仮名パピプペポ
濁点重複:バ゛ビ゛
ヴィー、ヴィー


全角ひらがなを半角カナへ
zhira2han
げ⇒ゲ こ⇒コ ご⇒ゴ さ⇒サ ざ⇒ザ し⇒シ じ⇒ジ す⇒ス ず⇒ズ せ⇒セ

test =
全角平仮名:アイウエケ、半角片仮名アイウエオ、
濁点平仮名:ガギクゲゴ、濁点半角片仮名ガギグゲゴ
半濁平仮名:パピプペボ、半濁半角片仮名パピプペポ
濁点重複:バ゙ビ゙
ヴィー、ヴィー


全角カタカナを半角カナへ
zkata2han
ク⇒ク グ⇒グ ケ⇒ケ ゲ⇒ゲ コ⇒コ ゴ⇒ゴ サ⇒サ ザ⇒ザ シ⇒シ ジ⇒ジ

test =
全角平仮名:あいうえお、半角片仮名アイウエオ、
濁点平仮名:がぎくげご、濁点半角片仮名ガギグゲゴ
半濁平仮名:ぱぴぷぺぼ、半濁半角片仮名パピプペポ
濁点重複:バ゙ビ゙
ヴィー、ヴィー


全角かなを半角カナへ
zkana2han
げ⇒ゲ こ⇒コ ご⇒ゴ さ⇒サ ざ⇒ザ し⇒シ じ⇒ジ す⇒ス ず⇒ズ せ⇒セ

test =
全角平仮名:アイウエケ、半角片仮名アイウエオ、
濁点平仮名:ガギクゲゴ、濁点半角片仮名ガギグゲゴ
半濁平仮名:パピプペボ、半濁半角片仮名パピプペポ
濁点重複:バ゙ビ゙
ヴィー、ヴィー


半角カナを全角カタカナへ
han2kata
オ⇒オ カ⇒カ ガ⇒ガ キ⇒キ ギ⇒ギ ク⇒ク グ⇒グ ケ⇒ケ ゲ⇒ゲ コ⇒コ

test =
全角平仮名:あいうえお、半角片仮名アイウエオ、
濁点平仮名:がぎくげご、濁点半角片仮名ガギグゲゴ
半濁平仮名:ぱぴぷぺぼ、半濁半角片仮名パピプペポ
濁点重複:バ゛ビ゛
ヴィー、ヴィー

[root@l22dm ~]#

 /usr/local/lib/python2.6/site-packages/mire/jpcode.py


#!/usr/loca/bin/python2.6
# -*- coding: UTF8 -*-

u"""
######################################################################
# 1. reverse(s) : Unicode文字列用の降順並替
# 2. sort(s) : Unicode文字列用の昇順並替
# 3. kana_conv(s, : 半角カナの全角カナ変換
# mode : hira(既定) = 半角カタカナを全角ひらがなへ
# : zkata2hira = 全角カタカナを全角ひらがなへ
# : zhira2kata = 全角ひらがなを全角カタカナへ
# : zhira2han = 全角ひらがなを半角カナへ
# : zkata2han = 全角カタカナを半角カナへ
# : zkana2han = 全角平片カナを半角カナへ
# : その他 = 半角カタカナを全角カタカナへ
#  全て変換用辞書に依存し変換する仕組み。濁点・半濁点の判別の為、逆順の
# 文字列を使って処理後、再度逆順にする手法を用いている。
#【更新履歴】
# 2010-05-05 初版 kana2zenとして半角カナを全角のカタカナひらがなへの変換機能
# 及び、そのテストコードを公開
# 2010-05-06 半角への逆変換が欲しくなったので機能拡張し、kana_convとした
# debug時に参照辞書の一部を確認可能にし、指定ミスを発見し易くした
# 長音記号等漏れ等の誤りを補正。多分精度的にはまだα1クラス。
# 2012-01-13 通りすがりさんご指摘の'け''ケ'のマッピングミスを修正
"""

__author__ = "Mire in Japan"
__version__ = '0.0.1a'
__copyright__ = 'Copyright (c) 2010 Mire'
__license__ = 'GPL'
__url__ = 'http://pythonlife.seesaa.net/article/148816739.html'

## 半角カナ⇒全角ひらがな辞書 ##
han2hira = { u'ア' :u'あ', u'イ' :u'い', u'ウ' :u'う', u'エ' :u'え', u'オ' :u'お'
, u'カ' :u'か', u'キ' :u'き', u'ク' :u'く', u'ケ' :u'', u'コ' :u'こ'
, u'サ' :u'さ', u'シ' :u'し', u'ス' :u'す', u'セ' :u'せ', u'ソ' :u'そ'
, u'タ' :u'た', u'チ' :u'ち', u'ツ' :u'つ', u'テ' :u'て', u'ト' :u'と'
, u'ナ' :u'な', u'ニ' :u'に', u'ヌ' :u'ぬ', u'ネ' :u'ね', u'ノ' :u'の'
, u'ハ' :u'は', u'ヒ' :u'ひ', u'フ' :u'ふ', u'ヘ' :u'へ', u'ホ' :u'ほ'
, u'マ' :u'ま', u'ミ' :u'み', u'ム' :u'む', u'メ' :u'め', u'モ' :u'も'
, u'ヤ' :u'や', u'ユ' :u'ゆ', u'ヨ' :u'よ', u'゚' :u'゜', u'゙' :u'゛'
, u'ラ' :u'ら', u'リ' :u'り', u'ル' :u'る', u'レ' :u'れ', u'ロ' :u'ろ'
, u'ワ' :u'わ', u'ン' :u'ん', u'「' :u'「', u'」' :u'」', u'。' :u'。'
, u'、' :u'、', u'・' :u'・', u'ァ' :u'ぁ', u'ィ' :u'ぃ', u'ゥ' :u'ぅ'
, u'ェ' :u'ぇ', u'ォ' :u'ぉ', u'ャ' :u'ゃ', u'ュ' :u'ゅ', u'ョ' :u'ょ'

, u'ガ':u'が', u'ギ':u'ぎ', u'グ':u'ぐ', u'ゲ':u'げ', u'ゴ':u'ご'
, u'ザ':u'ざ', u'ジ':u'じ', u'ズ':u'ず', u'ゼ':u'ぜ', u'ゾ':u'ぞ'
, u'ダ':u'だ', u'ヂ':u'ぢ', u'ヅ':u'づ', u'デ':u'で', u'ド':u'ど'
, u'バ':u'ば', u'ビ':u'び', u'ブ':u'ぶ', u'ベ':u'べ', u'ボ':u'ぼ'
, u'パ':u'ぱ', u'ピ':u'ぴ', u'プ':u'ぷ', u'ペ':u'ぺ', u'ポ':u'ぽ'
, u'ヲ':u'を' , u'ー':u'ー'}

## 半角カナ⇒全角カタカナ辞書 ##
han2kata = { u'ア' :u'ア', u'イ' :u'イ', u'ウ' :u'ウ', u'エ' :u'エ', u'オ' :u'オ'
, u'カ' :u'カ', u'キ' :u'キ', u'ク' :u'ク', u'ケ' :u'ケ', u'コ' :u'コ'
, u'サ' :u'サ', u'シ' :u'シ', u'ス' :u'ス', u'セ' :u'セ', u'ソ' :u'ソ'
, u'タ' :u'タ', u'チ' :u'チ', u'ツ' :u'ツ', u'テ' :u'テ', u'ト' :u'ト'
, u'ナ' :u'ナ', u'ニ' :u'ニ', u'ヌ' :u'ヌ', u'ネ' :u'ネ', u'ノ' :u'ノ'
, u'ハ' :u'ハ', u'ヒ' :u'ヒ', u'フ' :u'フ', u'ヘ' :u'ヘ', u'ホ' :u'ホ'
, u'マ' :u'マ', u'ミ' :u'ミ', u'ム' :u'ム', u'メ' :u'メ', u'モ' :u'モ'
, u'ヤ' :u'ヤ', u'ユ' :u'ユ', u'ヨ' :u'ヨ', u'゚' :u'゜', u'゙' :u'゛'
, u'ラ' :u'ラ', u'リ' :u'リ', u'ル' :u'ル', u'レ' :u'レ', u'ロ' :u'ロ'
, u'ワ' :u'ワ', u'ン' :u'ン', u'「' :u'「', u'」' :u'」', u'。' :u'。'
, u'、' :u'、', u'・' :u'・', u'ァ' :u'ァ', u'ィ' :u'ィ', u'ゥ' :u'ゥ'
, u'ェ' :u'ェ', u'ォ' :u'ォ', u'ャ' :u'ャ', u'ュ' :u'ュ', u'ョ' :u'ョ'

, u'ガ':u'ガ', u'ギ':u'ギ', u'グ':u'グ', u'ゲ':u'ゲ', u'ゴ':u'ゴ'
, u'ザ':u'ザ', u'ジ':u'ジ', u'ズ':u'ズ', u'ゼ':u'ゼ', u'ゾ':u'ゾ'
, u'ダ':u'ダ', u'ヂ':u'ヂ', u'ヅ':u'ヅ', u'デ':u'デ', u'ド':u'ド'
, u'バ':u'バ', u'ビ':u'ビ', u'ブ':u'ブ', u'ベ':u'ベ', u'ボ':u'ボ'
, u'パ':u'パ', u'ピ':u'ピ', u'プ':u'プ', u'ペ':u'ペ', u'ポ':u'ポ'
, u'ヴ':u'ヴ' #全角カタカナのみ「ヴ」がある!
, u'ヲ' :u'ヲ', u'ー':u'ー'}

## 全角ひらがな⇒全角カタカナ辞書 ##
hira2kata = { u'あ':u'ア', u'い':u'イ', u'う':u'ウ', u'え':u'エ', u'お':u'オ'
, u'か':u'カ', u'き':u'キ', u'く':u'ク', u'':u'ケ', u'こ':u'コ'
, u'さ':u'サ', u'し':u'シ', u'す':u'ス', u'せ':u'セ', u'そ':u'ソ'
, u'た':u'タ', u'ち':u'チ', u'つ':u'ツ', u'て':u'テ', u'と':u'ト'
, u'な':u'ナ', u'に':u'ニ', u'ぬ':u'ヌ', u'ね':u'ネ', u'の':u'ノ'
, u'は':u'ハ', u'ひ':u'ヒ', u'ふ':u'フ', u'へ':u'ヘ', u'ほ':u'ホ'
, u'ま':u'マ', u'み':u'ミ', u'む':u'ム', u'め':u'メ', u'も':u'モ'
, u'や':u'ヤ', u'ゆ':u'ユ', u'よ':u'ヨ', u'゜':u'゜', u'゛':u'゛'
, u'ら':u'ラ', u'り':u'リ', u'る':u'ル', u'れ':u'レ', u'ろ':u'ロ'
, u'わ':u'ワ', u'ん':u'ン', u'「':u'「', u'」':u'」', u'。':u'。'
, u'、':u'、', u'・':u'・', u'ぁ':u'ァ', u'ぃ':u'ィ', u'ぅ':u'ゥ'
, u'ぇ':u'ェ', u'ぉ':u'ォ', u'ゃ':u'ャ', u'ゅ':u'ュ', u'ょ':u'ョ'

, u'が':u'ガ', u'ぎ':u'ギ', u'ぐ':u'グ', u'げ':u'ゲ', u'ご':u'ゴ'
, u'ざ':u'ザ', u'じ':u'ジ', u'ず':u'ズ', u'ぜ':u'ゼ', u'ぞ':u'ゾ'
, u'だ':u'ダ', u'ぢ':u'ヂ', u'づ':u'ヅ', u'で':u'デ', u'ど':u'ド'
, u'ば':u'バ', u'び':u'ビ', u'ぶ':u'ブ', u'べ':u'ベ', u'ぼ':u'ボ'
, u'ぱ':u'パ', u'ぴ':u'ピ', u'ぷ':u'プ', u'ぺ':u'ペ', u'ぽ':u'ポ'
, u'う゛':u'ヴ'
, u'を':u'ヲ'}

## 全角カタカナ⇒全角ひらがな辞書 ##
kata2hira = { u'ア':u'あ', u'イ':u'い', u'ウ':u'う', u'エ':u'え', u'オ':u'お'
, u'カ':u'か', u'キ':u'き', u'ク':u'く', u'ケ':u'', u'コ':u'こ'
, u'サ':u'さ', u'シ':u'し', u'ス':u'す', u'セ':u'せ', u'ソ':u'そ'
, u'タ':u'た', u'チ':u'ち', u'ツ':u'つ', u'テ':u'て', u'ト':u'と'
, u'ナ':u'な', u'ニ':u'に', u'ヌ':u'ぬ', u'ネ':u'ね', u'ノ':u'の'
, u'ハ':u'は', u'ヒ':u'ひ', u'フ':u'ふ', u'ヘ':u'へ', u'ホ':u'ほ'
, u'マ':u'ま', u'ミ':u'み', u'ム':u'む', u'メ':u'め', u'モ':u'も'
, u'ヤ':u'や', u'ユ':u'ゆ', u'ヨ':u'よ', u'゜':u'゜', u'゛':u'゛'
, u'ラ':u'ら', u'リ':u'り', u'ル':u'る', u'レ':u'れ', u'ロ':u'ろ'
, u'ワ':u'わ', u'ン':u'ん', u'「':u'「', u'」':u'」', u'。':u'。'
, u'、':u'、', u'・':u'・', u'ァ':u'ぁ', u'ィ':u'ぃ', u'ゥ':u'ぅ'
, u'ェ':u'ぇ', u'ォ':u'ぉ', u'ャ':u'ゃ', u'ュ':u'ゅ', u'ョ':u'ょ'

, u'ガ':u'が', u'ギ':u'ぎ', u'グ':u'ぐ', u'ゲ':u'げ', u'ゴ':u'ご'
, u'ザ':u'ざ', u'ジ':u'じ', u'ズ':u'ず', u'ゼ':u'ぜ', u'ゾ':u'ぞ'
, u'ダ':u'だ', u'ヂ':u'ぢ', u'ヅ':u'づ', u'デ':u'で', u'ド':u'ど'
, u'バ':u'ば', u'ビ':u'び', u'ブ':u'ぶ', u'ベ':u'べ', u'ボ':u'ぼ'
, u'パ':u'ぱ', u'ピ':u'ぴ', u'プ':u'ぷ', u'ペ':u'ぺ', u'ポ':u'ぽ'
, u'ヴ':u'う゛'
, u'ヲ':u'を'}

## 全角カタカナ⇒半角カナ辞書 ##
kata2han = { u'ア':u'ア', u'イ':u'イ', u'ウ':u'ウ', u'エ':u'エ', u'オ':u'ケ'
, u'カ':u'カ', u'キ':u'キ', u'ク':u'ク', u'ケ':u'ケ', u'コ':u'コ'
, u'サ':u'サ', u'シ':u'シ', u'ス':u'ス', u'セ':u'セ', u'ソ':u'ソ'
, u'タ':u'タ', u'チ':u'チ', u'ツ':u'ツ', u'テ':u'テ', u'ト':u'ト'
, u'ナ':u'ナ', u'ニ':u'ニ', u'ヌ':u'ヌ', u'ネ':u'ネ', u'ノ':u'ノ'
, u'ハ':u'ハ', u'ヒ':u'ヒ', u'フ':u'フ', u'ヘ':u'ヘ', u'ホ':u'ホ'
, u'マ':u'マ', u'ミ':u'ミ', u'ム':u'ム', u'メ':u'メ', u'モ':u'モ'
, u'ヤ':u'ヤ', u'ユ':u'ユ', u'ヨ':u'ヨ', u'゜':u'゚', u'゛':u'゙'
, u'ラ':u'ラ', u'リ':u'リ', u'ル':u'ル', u'レ':u'レ', u'ロ':u'ロ'
, u'ワ':u'ワ', u'ン':u'ン', u'「':u'「', u'」':u'」', u'。':u'。'
, u'、':u'、', u'・':u'・', u'ァ':u'ァ', u'ィ':u'ィ', u'ゥ':u'ゥ'
, u'ェ':u'ェ', u'ォ':u'ォ', u'ャ':u'ャ', u'ュ':u'ュ', u'ョ':u'ョ'

, u'ガ':u'ガ', u'ギ':u'ギ', u'グ':u'グ', u'ゲ':u'ゲ', u'ゴ':u'ゴ'
, u'ザ':u'ザ', u'ジ':u'ジ', u'ズ':u'ズ', u'ゼ':u'ゼ', u'ゾ':u'ゾ'
, u'ダ':u'ダ', u'ヂ':u'ヂ', u'ヅ':u'ヅ', u'デ':u'デ', u'ド':u'ド'
, u'バ':u'バ', u'ビ':u'ビ', u'ブ':u'ブ', u'ベ':u'ベ', u'ボ':u'ボ'
, u'パ':u'バ', u'ピ':u'ピ', u'プ':u'プ', u'ペ':u'ペ', u'ポ':u'ポ'
, u'ヴ':u'ヴ'
, u'ヲ':u'ヲ' , u'ー':u'ー'}

## 全角ひらがな⇒全角カタカナ辞書 ##
hira2han = { u'あ' :u'ア', u'い' :u'イ', u'う' :u'ウ', u'え' :u'エ', u'お' :u'オ'
, u'か' :u'カ', u'き' :u'キ', u'く' :u'ク', u'' :u'ケ', u'こ' :u'コ'
, u'さ' :u'サ', u'し' :u'シ', u'す' :u'ス', u'せ' :u'セ', u'そ' :u'ソ'
, u'た' :u'タ', u'ち' :u'チ', u'つ' :u'ツ', u'て' :u'テ', u'と' :u'ト'
, u'な' :u'ナ', u'に' :u'ニ', u'ぬ' :u'ヌ', u'ね' :u'ネ', u'の' :u'ノ'
, u'は' :u'ハ', u'ひ' :u'ヒ', u'ふ' :u'フ', u'へ' :u'ヘ', u'ほ' :u'ホ'
, u'ま' :u'マ', u'み' :u'ミ', u'む' :u'ム', u'め' :u'メ', u'も' :u'モ'
, u'や' :u'ヤ', u'ゆ' :u'ユ', u'よ' :u'ヨ', u'゜' :u'゚', u'゛' :u'゙'
, u'ら' :u'ラ', u'り' :u'リ', u'る' :u'ル', u'れ' :u'レ', u'ろ' :u'ロ'
, u'わ' :u'ワ', u'ん' :u'ン', u'「' :u'「', u'」' :u'」', u'。' :u'。'
, u'、' :u'、', u'・' :u'・', u'ぁ' :u'ァ', u'ぃ' :u'ィ', u'ぅ' :u'ゥ'
, u'ぇ' :u'ェ', u'ぉ' :u'ォ', u'ゃ' :u'ャ', u'ゅ' :u'ュ', u'ょ' :u'ョ'

, u'が':u'ガ', u'ぎ':u'ギ', u'ぐ':u'グ', u'げ':u'ゲ', u'ご':u'ゴ'
, u'ざ':u'ザ', u'じ':u'ジ', u'ず':u'ズ', u'ぜ':u'ゼ', u'ぞ':u'ゾ'
, u'だ':u'ダ', u'ぢ':u'ヂ', u'づ':u'ヅ', u'で':u'デ', u'ど':u'ド'
, u'ば':u'バ', u'び':u'ビ', u'ぶ':u'ブ', u'べ':u'ベ', u'ぼ':u'ボ'
, u'ぱ':u'パ', u'ぴ':u'ピ', u'ぷ':u'プ', u'ぺ':u'ペ', u'ぽ':u'ポ'
, u'を':u'ヲ' , u'ー':u'ー'}

## 全角ひらがなカタカナ⇒半角カナ辞書 ##
zen2han = { u'ア':u'ア', u'イ':u'イ', u'ウ':u'ウ', u'エ':u'エ', u'オ':u'ケ'
, u'カ':u'カ', u'キ':u'キ', u'ク':u'ク', u'ケ':u'ケ', u'コ':u'コ'
, u'サ':u'サ', u'シ':u'シ', u'ス':u'ス', u'セ':u'セ', u'ソ':u'ソ'
, u'タ':u'タ', u'チ':u'チ', u'ツ':u'ツ', u'テ':u'テ', u'ト':u'ト'
, u'ナ':u'ナ', u'ニ':u'ニ', u'ヌ':u'ヌ', u'ネ':u'ネ', u'ノ':u'ノ'
, u'ハ':u'ハ', u'ヒ':u'ヒ', u'フ':u'フ', u'ヘ':u'ヘ', u'ホ':u'ホ'
, u'マ':u'マ', u'ミ':u'ミ', u'ム':u'ム', u'メ':u'メ', u'モ':u'モ'
, u'ヤ':u'ヤ', u'ユ':u'ユ', u'ヨ':u'ヨ', u'゜':u'゚', u'゛':u'゙'
, u'ラ':u'ラ', u'リ':u'リ', u'ル':u'ル', u'レ':u'レ', u'ロ':u'ロ'
, u'ワ':u'ワ', u'ン':u'ン', u'「':u'「', u'」':u'」', u'。':u'。'
, u'、':u'、', u'・':u'・', u'ァ':u'ァ', u'ィ':u'ィ', u'ゥ':u'ゥ'
, u'ェ':u'ェ', u'ォ':u'ォ', u'ャ':u'ャ', u'ュ':u'ュ', u'ョ':u'ョ'

, u'ガ':u'ガ', u'ギ':u'ギ', u'グ':u'グ', u'ゲ':u'ゲ', u'ゴ':u'ゴ'
, u'ザ':u'ザ', u'ジ':u'ジ', u'ズ':u'ズ', u'ゼ':u'ゼ', u'ゾ':u'ゾ'
, u'ダ':u'ダ', u'ヂ':u'ヂ', u'ヅ':u'ヅ', u'デ':u'デ', u'ド':u'ド'
, u'バ':u'バ', u'ビ':u'ビ', u'ブ':u'ブ', u'ベ':u'ベ', u'ボ':u'ボ'
, u'パ':u'バ', u'ピ':u'ピ', u'プ':u'プ', u'ペ':u'ペ', u'ポ':u'ポ'
, u'ヴ':u'ヴ'
, u'ヲ':u'ヲ'

, u'あ' :u'ア', u'い' :u'イ', u'う' :u'ウ', u'え' :u'エ', u'お' :u'オ'
, u'か' :u'カ', u'き' :u'キ', u'く' :u'ク', u'' :u'ケ', u'こ' :u'コ'
, u'さ' :u'サ', u'し' :u'シ', u'す' :u'ス', u'せ' :u'セ', u'そ' :u'ソ'
, u'た' :u'タ', u'ち' :u'チ', u'つ' :u'ツ', u'て' :u'テ', u'と' :u'ト'
, u'な' :u'ナ', u'に' :u'ニ', u'ぬ' :u'ヌ', u'ね' :u'ネ', u'の' :u'ノ'
, u'は' :u'ハ', u'ひ' :u'ヒ', u'ふ' :u'フ', u'へ' :u'ヘ', u'ほ' :u'ホ'
, u'ま' :u'マ', u'み' :u'ミ', u'む' :u'ム', u'め' :u'メ', u'も' :u'モ'
, u'や' :u'ヤ', u'ゆ' :u'ユ', u'よ' :u'ヨ', u'゜' :u'゚', u'゛' :u'゙'
, u'ら' :u'ラ', u'り' :u'リ', u'る' :u'ル', u'れ' :u'レ', u'ろ' :u'ロ'
, u'わ' :u'ワ', u'ん' :u'ン'
, u'、' :u'、', u'・' :u'・', u'ぁ' :u'ァ', u'ぃ' :u'ィ', u'ぅ' :u'ゥ'
, u'ぇ' :u'ェ', u'ぉ' :u'ォ', u'ゃ' :u'ャ', u'ゅ' :u'ュ', u'ょ' :u'ョ'

, u'が':u'ガ', u'ぎ':u'ギ', u'ぐ':u'グ', u'げ':u'ゲ', u'ご':u'ゴ'
, u'ざ':u'ザ', u'じ':u'ジ', u'ず':u'ズ', u'ぜ':u'ゼ', u'ぞ':u'ゾ'
, u'だ':u'ダ', u'ぢ':u'ヂ', u'づ':u'ヅ', u'で':u'デ', u'ど':u'ド'
, u'ば':u'バ', u'び':u'ビ', u'ぶ':u'ブ', u'べ':u'ベ', u'ぼ':u'ボ'
, u'ぱ':u'パ', u'ぴ':u'ピ', u'ぷ':u'プ', u'ぺ':u'ペ', u'ぽ':u'ポ'
, u'を':u'ヲ' , u'ー':u'ー'}

def reverse(s):
"""
Unicode文字列用の降順並替
"""
st = u'%s' % (s)
r = []
for i in st: r.append(i)
r.reverse()
rs = u''
for i in r: rs = rs + i
return rs

def sort(s):
"""
Unicode文字列用の昇順並替
"""
st = u'%s' % (s)
r = []
for i in st: r.append(i)
r.sort()
rs = u''
for i in r: rs = rs + i
return rs

def kana_conv(s, mode='han2hira', debug=0):
u"""
半角カナの全角カナ変換
第一引数に変換対象文字列を指定。
mode='hira'(既定): ひらがなへ
それ以外なら カナカナへ
"""
conv_dic={}
## モード設定により辞書を選択 ##
if mode.lower() == 'zkana2han':
conv_dic = zen2han
daku = [u'゛', u'゜']
#print '全角かなを半角カナへ'
elif mode.lower() == 'zkata2han':
conv_dic = kata2han
daku = [u'゛', u'゜']
elif mode.lower() == 'zhira2han':
conv_dic = hira2han
daku = [u'゛', u'゜']
elif mode.lower() == 'han2hira':
conv_dic = han2hira
daku = [u'゙', u'゚']
elif mode.lower() == 'kata2hira':
conv_dic = kata2hira
daku = [u'゛', u'゜']
elif mode.lower() == 'hira2kata':
conv_dic = hira2kata
daku = [u'゛', u'゜']
#print '全角ひらがなを全角カタカナへ'
elif mode.lower() == 'kata2han':
conv_dic = kata2han
daku = [u'゛', u'゜']
#print '全角を半角カナへ'
else:
conv_dic = han2kata
daku = [u'゙', u'゚']
#print '半角を全角カタカナへ'

if debug>0:
conv_ks = conv_dic.keys()
conv_ks.sort()
for i in range(10):
print u'%s⇒%s' % (conv_ks[20+i],conv_dic[conv_ks[20+i]]),
print

## 処理用の文字列を作成 ##
o = u'%s' % (unicode(s)) # 濁音半濁音処理の為お尻から処理したいので
o = reverse(o) # Unicode文字として並びを反転した上で

## 処理用文字列で1文字ずつ処理 ##
z = p = u'' # 処理用文字列の初期化
for h in o: # 1文字ずつ
if h in conv_dic: # 半角カナの範囲EFBDA1-EFBE9Fの辞書にあるなら
if h in daku: # 濁点、半濁点なら
if p in daku: # ひとつ前もそうなら
z = z + conv_dic[p] # 前のものを全角の濁点、半濁点に変換
p=u'%s' % (h) # 文字をpで記憶
else:
k = u'%s%s' % (h, p)
if k in conv_dic: # 濁点、半濁点付の候補があれば
z = z + reverse(conv_dic[k]) # その文字に変換は
else: # そうでないなら、仕方ないので
z = z + conv_dic[p] # 全角の濁点、半濁点に変換
z = z + conv_dic[h] # 辞書で全角分に置換して文字列を作る
p = u'' # 処理が済んだのでpの記憶を消去し通常モードに

else: # それ以外は
if not p == u'': # pに記憶があるなら
z = z + conv_dic[p] # その全角分を単独で登録
p = u'' # 処理が済んだのでpの記憶を消去し通常モードに

z = z + h # そのままの文字を追加

## 全文字の処理が終わったら ##
return reverse(z) # 作成した文字列を文字単位で反転
# その変換した文字列を返す


def _test(debug=1):
test = u"""
test =
全角平仮名:あいうえお、半角片仮名アイウエオ、
濁点平仮名:がぎくげご、濁点半角片仮名ガギグゲゴ
半濁平仮名:ぱぴぷぺぼ、半濁半角片仮名パピプペポ
濁点重複:バ゙ビ゙
ヴィー、ヴィー
"""
from sys import argv
keys = han2kata.keys()
ks=''
for k in keys:
ks = ks + k
# print ks
# print kana_conv(ks, debug=1)
# print kana_conv(ks, mode='han2kata', debug=1)
# print
# print sort(kana_conv(ks), debug=1)
# print sort(kana_conv(ks, mode='han2kata', debug=1))
# ソースを読んでその半角カナを変換し全角間変換辞書ソースドを作成
fpi =open(argv[0],'r')
lines = fpi.readlines()
for li in lines:
pass
# print kana_conv(li, mode='han2kata', debug=1),
fpi.close()

# han2hira反転辞書を作成
#  半角カナーの変換辞書作成をここのテストコードで先ず行ない。
# それでソースコードを変換し、その並びを整えた辞書定義のソースを取得した。)
try:
key = han2kata.keys()
key.sort()
#hira2han={}
d=[]
for k in keys:
try:
#hira2han[han2kata[k]]=k
d.append(u"u'%s':'%s'" % (han2kata[k], k))
except:
from mire.std import display_err
display_err(locals())
d.sort()
# print 'kata2han={%s}' % (', '.join(d))
except:
from mire.std import display_err
display_err(locals())

# ソースを読んでその半角カナを変換し全角間変換辞書定義のソースコードを作成
fpi =open(argv[0],'r')
lines = fpi.readlines()
for li in lines:
pass
# print kana_conv(li, mode='2han', debug=1),
fpi.close()


print 'test orignal text'
print test
mode_names={ 'han2hira' :'半角カナを全角ひらがなへ'
, 'zkana2han' :'全角かなを半角カナへ'
, 'zkata2hira':'全角片仮名を全角平仮名へ'
, 'zhira2kata':'全角ひらがなを全角カタカナへ'
, 'zhira2han' :'全角ひらがなを半角カナへ'
, 'zkata2han' :'全角カタカナを半角カナへ'
, 'han2kata' :'半角カナを全角カタカナへ'}
modes=['han2hira', 'zkata2hira', 'zhira2kata', 'zhira2han', 'zkata2han', 'zkana2han', 'han2kata']
try:
for m in modes:
print
print mode_names[m]
print m
print kana_conv(test, mode=m, debug=1)
except:
from mire.std import display_err
display_err(locals())


if __name__ == '__main__':
from mire.std import display_err
_test()
タグ:Unicode Python
posted by Mire at 13:57 | Comment(2) | TrackBack(0) | Pythonプログラミング | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
 通りすがり さん、チェック下さり有難うございます。単純なケアレスミスを犯してしまっていますね。不完全なものを掲載し誠に失礼しました。お詫び申し上げます。

 ご指摘下さった点、ver0.0.1aとして修正させて頂きました。
Posted by mire at 2017年06月24日 04:12
こんにちは。

実際に使わせていただいたものです。お世話になってます。
u'ケ':u'お'
u'ケ' :u'お'
u'お' :u'ケ'←こんな感じで、ケのところが おに変わってしまったりするので、修正された方がいいかと思い、コメントいたしました。
Posted by 通りすがり at 2012年01月05日 19:48
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
※ブログオーナーが承認したコメントのみ表示されます。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/148816739
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック
月額見放題1,000円開始キャンペーンバナー(画像ありver)
紺碧の艦隊 ルパン三世 GREAT CHASE クリックプロモーション
<< 2013年01月 >>
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
カテゴリ
タグクラウド
ファン
利用中のオープンソース
最近のコメント
最近の記事
過去ログ
QRコード
レガシーなアプリはいかが?
Dell 法人のお客様ページ
  • 【法人様向け】デル、お得なキャンペーン情報
  • 法人のお客様向け ストレージソリューション
  • 法人のお客様向け ネットワークソリューション
  • 【SOHO法人様向け】デル・オンライン広告限定ページ
  • デル-個人のお客様ページ
  • 【個人のお客様向け】デル・オンライン広告限定ページ
  • オンライン広告限定キャンペーンページ
  • ソフトウェア&周辺機器 パソコン工房
    ツートップインターネットショップ(twotop.co.jp) マウスコンピューター/G-Tune
  • ×

    この広告は1年以上新しい記事の投稿がないブログに表示されております。