ただし、あくまで半角文字が1で全角文字が2の環境の場合です。
Table of Contents
1 エンコーディングの記載
あまりお勧めしませんが、ソースコードに全角文字列を埋め込む場合、ファイル先頭にUTF-8でエンコーディングされている旨を記載してpythonインタプリタに認識させる必要があります。
# -*- coding: utf-8 -*-
今回は全角文字列の幅を取得するコードを扱う為、ソースコードの先頭にエンコーディングを記載します。
2 全角文字の扱い
uをつけた場合はUTF-8文字列として扱われます。
>>> print(len(u'こんにちは、world')) 11
uをつけなかった場合はバイト列として扱われます(UTF-8の場合、日本語の文字は3Byteで表現されます)。
>>> print(len('こんにちは、world')) 23
バイト列を探索してutf-8の文字を判定すれば幅を割り出せますが、すでにunicodedataという便利なライブラリがその処理を実行してくれています。
3 unicodedata.east_asian_widthで文字幅取得
unicodedata.east_asian_widthメソッドで文字の種類を判別します。Asciiコードは'Na'、全角文字は'W'、半角カナは'H'が返ってきます。これを利用し、文字幅と文字列幅を以下のように算出します。
# -*- coding: utf-8 -*- import unicodedata def get_char_width(c): data = unicodedata.east_asian_width(c) if data == 'Na' or data == 'H': return 1 return 2 def get_string_width(string): width = 0 for c in string: width += get_char_width(c) return width string = u'コんにちは、world' print('%s' % string) print('-' * get_string_width(string)) print('len(string) = %d' % len(string)) print('get_string_width(string) = %d' % get_string_width(string))
'コんにちは、world'という文字列の文字数は11となります。'コ'は1、'んにちは、'は10、'w'は2、'orld'は4の幅と計算されます。
コんにちは、world ----------------- len(string) = 11 get_string_width(string) = 17
*上のコードに以下のnormalize_stringという関数を追加して、幅の最大値を超えない文字列のインデックス値を探索します。
def normalize_string(string, max_width): index = 0 sum_width = 0 while index < len(string): c_width = get_char_width(string[index]) if sum_width + c_width > max_width: break sum_width += c_width index += 1 return string[0:index] ... print('normalize_string(string, 10) = %s' % normalize_string(string, 10)) print('normalize_string(string, 11) = %s' % normalize_string(string, 11)) print('normalize_string(string, 12) = %s' % normalize_string(string, 12)) print('normalize_string(string, 13) = %s' % normalize_string(string, 13)) print('normalize_string(string, 14) = %s' % normalize_string(string, 14))
実行結果は以下のようになりました。
normalize_string(string, 10) = コんにちは normalize_string(string, 11) = コんにちは、 normalize_string(string, 12) = コんにちは、 normalize_string(string, 13) = コんにちは、w normalize_string(string, 14) = コんにちは、wo