Pythonで半角全角混じりのテキストを複数行に折り返す

2022-03-16  /  Python

OGP 画像生成のため、半角全角混じりのテキストを複数行に整形したかったので調べました。同じ問題に対応されている方のコードがあったので助かりました。

標準の textwrap.wrap では右端がガタガタしやすい

以下のテキストを 10 文字ずつに改行しようと思います。

textwrap モジュールは、実際の処理を行う TextWrapper とともに、いくつかの便利な関数を提供しています。

>>> import textwrap
>>> text = "textwrap モジュールは、実際の処理を行う TextWrapper とともに、いくつかの便利な関数を提供しています。"
>>> [len(t) for t in textwrap.wrap(text, 10)]
[10, 10, 10, 10, 10, 10, 1]
>>> [print(t) for t in textwrap.wrap(text, 10)]
textwrap モ
ジュールは実際の処
理を行う TextW
rapper ととも
いくつかの便利な
関数を提供しています

[None, None, None, None, None, None, None]

このように標準の textwrap.wrap を使用すると文字数で整形されるため半角文字が混ざった行は短くなってしまいます。当然の結果です。

textwrap モ
ジュールは、実際の処
理を行う TextW
rapper ととも
に、いくつかの便利な
関数を提供しています

単純に文字数では無く文字の幅を考慮して、半角文字では 20 文字分、全角文字なら 10 文字分になるように整形する必要があります。

半角全角に対応したクラスを利用する

探してみるとまさに同じ問題に対応されているコードが公開されていました。

Python の textwrap.wrap()が日本語で崩れる問題 — 清水川 Web

textwrap.TextWrapper を継承したクラスを実装されています。ありがたくこちらのコードを利用して整形してみました。 textwrapper.py というファイルにして wrap で呼び出せるようにしています。

>>> import textwrapper
>>> text = "textwrap モジュールは、実際の処理を行う TextWrapper とともに、いくつかの便利な関数を提供しています。"
>>> [len(t) for t in textwrapper.wrap(text, 10)]
[8, 5, 5, 5, 9, 6, 5, 5, 5, 5, 1]
>>> [print(t) for t in textwrapper.wrap(text, 10)]
textwrap
モジュール
実際の
処理を行う
TextWrapp
er ととも
いくつ
かの便利な
関数を提供
しています

[None, None, None, None, None, None, None, None, None, None, None]

先ほどとは異なりきれいに整形されていますね。

textwrap
モジュール
は、実際の
処理を行う
TextWrapp
er ととも
に、いくつ
かの便利な
関数を提供
しています

禁則処理とか言いだすと大変なのですが…OGP 画像前提なのでひとまずこれで問題なさそうです。

Published: 2022-03-16  /  Tags: Python