RubyとPythonで全角文字を半角文字2文字として数える
Rubyで左詰めを行うためにString#ljustを使ったが、文字列に全角文字や半角カナが混じると、予想していた空白の数に調整されなかった。そのためASCII文字と半角カナを判定して全角文字の数を数えてみた。ASCII文字と半角カナ以外の半角文字は考慮されていない。
Pythonでは、unicodedata.east_asian_widthを使用して全角と半角の文字を判別できるようだ。
追記:その2にて、RubyでもUnicodeのEast Asian Widthの定義を参照できるように修正した。ついでに右寄せと中央寄せも追加した。
Ruby 1.8.6
# 左寄せ def ljust_kana(str, size, pad = " ") space = size - width_kana(str) if space > 0 str += pad * space end return str end # 幅(半角基準) def width_kana(str) all = str.scan(/./u).size # 全文字数 zenkaku = count_zen(str) # 全角文字数 hankaku = all - zenkaku # 半角文字数 return zenkaku * 2 + hankaku end # 全角文字数(不完全) def count_zen(str) all = str.scan(/./u).size # 全文字数 ascii = str.scan(/[ -~]/u).size # ASCII文字数 kana = str.scan(/[。-゚]/u).size # 半角かな文字数 return all - (ascii + kana) end # main puts ljust_kana("日本語", 20) + "|" puts ljust_kana("ニホンゴ", 20) + "|" puts ljust_kana("nihongo", 20) + "|" puts ljust_kana("niホン語", 20) + "|"
Python 2.5.1
# -*- coding: utf-8 -*- import unicodedata # 左寄せ def ljust_kana(str, size, pad = " "): space = size - width_kana(str) if space > 0: str += pad * space return str # 幅(半角基準) def width_kana(str): all = len(str) # 全文字数 zenkaku = count_zen(str) # 全角文字数 hankaku = all - zenkaku # 半角文字数 return zenkaku * 2 + hankaku # 全角文字数 def count_zen(str): n = 0 for c in str: wide_chars = u"WFA" eaw = unicodedata.east_asian_width(c) if wide_chars.find(eaw) > -1: n += 1 return n # main if __name__ == "__main__": print ljust_kana(u"日本語", 20) + "|" print ljust_kana(u"ニホンゴ", 20) + "|" print ljust_kana(u"nihongo", 20) + "|" print ljust_kana(u"niホン語", 20) + "|"
結果
日本語 | ニホンゴ | nihongo | niホン語 |
実行環境 Mac OSX 10.5.6 Leopard