Pythonで文字列を折り返し・切り詰めして整形するtextwrap

Pythonで文字列を任意の文字数で折り返し(改行)、切り詰め(省略)して整形するには、標準ライブラリのtextwrapモジュールを使います。

6.4. textwrap — テキストの折り返しと詰め込み — Python 3.6.3 ドキュメント

ここでは以下の内容について説明します。

文字列を折り返し(改行): wrap(), fill() 文字列を切り詰め(省略): shorten() TextWrapperオブジェクト

出力時ではなくコード中の長い文字列を複数行に改行して書く場合は

また、文字列ではなくリストや辞書を整形して出力するにはpprintモジュールが便利です。

文字列を折り返し(改行): wrap(), fill()

textwrapモジュールの関数wrap()で、任意の文字数に収まるように単語の切れ目で分割したリストが取得できます。 第二引数widthに文字数を指定します。デフォルトはwidth=70。

import textwrap

s = "Python can be easy to pick up whether you're a first time programmer or you're experienced with other languages"

s_wrap_list = textwrap.wrap(s, 40)
print(s_wrap_list)
# ['Python can be easy to pick up whether', "you're a first time programmer or you're", 'experienced with other languages']

得られたリストを使って'\n'.join(list)とすると改行コード\nで改行された文字列が取得できます。

print('\n'.join(s_wrap_list))
# Python can be easy to pick up whether
# you're a first time programmer or you're
# experienced with other languages

関数fill()は、リストではなく改行された文字列を返します。上の例のようにwrap()のあとで'\n'.join(list)するのと同じ。 リストが必要なくターミナルなどに固定幅の文字列を出力したいときにはこちらのほうが便利です。

print(textwrap.fill(s, 40))
# Python can be easy to pick up whether
# you're a first time programmer or you're
# experienced with other languages

引数max_lineを指定すると、それ以降の行数は省略されます。

print(textwrap.wrap(s, 40, max_lines=2))
# ['Python can be easy to pick up whether', "you're a first time programmer or [...]"]

print(textwrap.fill(s, 40, max_lines=2))
# Python can be easy to pick up whether
# you're a first time programmer or [...]

省略される場合、デフォルトでは' [...]'が最後に出力されます。引数placeholderで任意の文字列に置き換えることができます。

print(textwrap.fill(s, 40, max_lines=2, placeholder=' ~'))
# Python can be easy to pick up whether
# you're a first time programmer or ~

また、引数initial_indentで最初の行の先頭に加えられる文字列を指定できます。段落の最初に字下げしたい場合などに使います。

print(textwrap.fill(s, 40, max_lines=2, placeholder=' ~', initial_indent='  '))
#   Python can be easy to pick up whether
# you're a first time programmer or ~

注意点: 全角半角 textwrapでは文字幅ではなく文字数で制御しており、半角も全角も一文字としてみなされます。 s = 'あいうえお、かきくけこ、12345,67890, さしすせそ、abcde'

print(textwrap.fill(s, 12))
# あいうえお、かきくけこ、
# 12345,67890,
# さしすせそ、abcde

半角全角が入り交じった日本語の文章などを固定幅で折り返したい場合は、以下のページが参考になります。

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

文字列を切り詰め(省略): shorten()

文字列を切り詰めて省略したい場合は、textwrapモジュールの関数shorten()を使います。 任意の文字数に収まるように単語単位で省略されます。省略を示す文字列(デフォルトでは' [...]'、引数placeholderで設定可能)も含めて任意の文字数に収まる

s = 'Python is powerful'

print(textwrap.shorten(s, 12))
# Python [...]

print(textwrap.shorten(s, 12, placeholder=' ~'))
# Python is ~

日本語の文字列の場合、単語に分割できないのでうまく省略できません。

s = 'Pythonについて。Pythonは汎用のプログラミング言語であります。'

print(textwrap.shorten(s, 20))
# [...]

単語単位ではなく、文字数だけ考慮して省略する場合は、以下のように簡単に実現できます。

s_short = s[:12] + '...'
print(s_short)
# Pythonについて。P...

半角、全角を考慮して文字幅をカウントしたい場合は、

TextWrapperオブジェクト

決まった設定で何度もwrap()やfill() を行う場合は、TextWrapperオブジェクトを生成しておくと効率が良い。

wrapper = textwrap.TextWrapper(width=30, max_lines=3, placeholder=' ~', initial_indent='  ')

s = "Python can be easy to pick up whether you're a first time programmer or you're experienced with other languages"

print(wrapper.wrap(s))
# ['  Python can be easy to pick', "up whether you're a first time", "programmer or you're ~"]

print(wrapper.fill(s))
#   Python can be easy to pick
# up whether you're a first time
# programmer or you're ~

同じ設定を再利用できます。

Last Updated: 6/26/2019, 10:34:03 PM