スクリプト書いていると、等幅フォント上で全角半角混じった文字列をピシッと
揃えたいときがよくあります。pythonのlen()は文字数を返すので、それでイケルと思ってしまいますが
s = 'hello' len(s) 5 # OK s = 'こんにちわ' len(s) 5 # (´・ω・`) max_width = max(len(s) for s in ['hello world', 'こんにちわ世界', 'ABCDE']) print(max_width) 11 for x in ['hello world', 'こんにちわ世界', 'ABCDE']: print(f'{x}{" " * (max_width - len(x))}: xxxxx') hello world: xxxxx こんにちわ世界: xxxxx ABCDE : xxxxx
となってしまいます。全角は2文字分の幅ですよーって
知りたいので、unicodedataモジュールのeast_asian_widthを使います。
def unicode_width(s: str) -> int: """ マルチバイトを考慮した文字幅を返します。 :param s: 対象文字列 :return: 文字幅 """ return sum([east_asian_width(c) in 'WF' and 2 or 1 for c in s])
for x in ['hello world', 'こんにちわ世界', 'ABCDE']: print(f'{x}{" " * (max_width - unicode_width(x))}: xxxxx') hello world : xxxxx こんにちわ世界: xxxxx ABCDE : xxxxx
ブラウザで見ると、ずれて見えちゃうかもなので、画像で。
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- try-python