ただし、あくまで半角文字が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