Python

【Python】長すぎる文字列を分割したり、折り返ししたり、切り詰めたりする方法

この記事では、Pythonで長すぎる文字列を文字数で分割したり、折り返ししたり、切り詰めたりする方法を解説します。これらの処理を実装するには標準ライブラリのtextwrapモジュールを使います。それでは、サンプルを交えて使い方を見ていきましょう!

区切り文字で分割したい場合は以下の記事を参照してください。

【Python】文字列を分割する方法【split】この記事では、Pythonで文字列を分割する方法を解説します。取得した文字列をうまいこと分割することで、必要な部分のみを抜き出してデータ化したり、見やすく整形したりすることができます。それでは、文字列の分割方法を見ていきましょう!...

文字列を文字数で分割する

文字列を文字数で分割するには、textwrapモジュールのwrap()関数を使います。

textwrap.wrap(text, width=70, **kwargs)

width引数を指定することで文字数を指定できます。

import textwrap

t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
print(textwrap.wrap(t, width=10))
print(textwrap.wrap(t, width=20))

t = 'あいうえおかきくけこさしすせそ'
print(textwrap.wrap(t, width=5))

実行結果

['ABCDEFGHIJ', 'KLMNOPQRST', 'UVWXYZ']
['ABCDEFGHIJKLMNOPQRST', 'UVWXYZ']
['あいうえお', 'かきくけこ', 'さしすせそ']

**kwargs引数にはTextWrapperインスタンスの属性を指定することができます。

LinkTextWrapper — Python ドキュメント

文字列を文字数で折り返す

文字列を文字数で折り返したい場合は、textwrapモジュールのfill()関数を使います。

textwrap.fill(text, width=70, **kwargs)

width引数を指定することで文字数を指定できます。

import textwrap

t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
print(textwrap.fill(t, width=10))
print(textwrap.fill(t, width=20))

t = 'あいうえおかきくけこさしすせそ'
print(textwrap.fill(t, width=5))

実行結果

ABCDEFGHIJ
KLMNOPQRST
UVWXYZ
ABCDEFGHIJKLMNOPQRST
UVWXYZ
あいうえお
かきくけこ
さしすせそ

**kwargs引数にはTextWrapperインスタンスの属性を指定することができます。

LinkTextWrapper — Python ドキュメント

文字数を超えた文字列を切り詰める

文字列を決まった文字数に切り詰めたい場合は、textwrapモジュールのshorten()関数を使います。

textwrap.shorten(text, width, **kwargs)

切り詰め時に使用される文字列の文字数もwidthに含まれるので注意が必要です。

import textwrap

t = 'The first step is always the hardest.'
print(textwrap.shorten(t, width=15))
print(textwrap.shorten(t, width=20))

実行結果

The first [...]
The first step [...]

また、切り詰めが行われる箇所は「空白」なので文字列中に空白がない場合は以下のような結果になります。

t = 'Thefirststepisalwaysthehardest.'
print(textwrap.shorten(t, width=15))
print(textwrap.shorten(t, width=20))

実行結果

[...]
[...]

**kwargs引数にはTextWrapperインスタンスの属性を指定することができます。

LinkTextWrapper — Python ドキュメント

大量に処理する場合はTextWrapperを使おう!

上記で紹介した関数たちは内部的にTextWrapperインスタンスを生成して処理を行っています。処理数が少ない場合はあまり気にする必要はありませんが、大量の文字列を処理する場合はTextWrapperインスタンスを生成した方が処理が早くなります。

例えば、以下のコードは10万個の文字列をwrap()関数を使って文字数で分割する速度を測っていますが、インスタンスを生成した方が早いことがわかります。

import textwrap
import time


# 時間を測る関数
def tic():
    # require  to import time
    global start_time_tictoc
    start_time_tictoc = time.time()

def toc(tag="elapsed time"):
    if "start_time_tictoc" in globals():
        print("{}: {:.9f} [sec]".format(tag, time.time() - start_time_tictoc))
    else:
        print("tic has not been called")


# 大量の文字列を生成
t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
texts = [t for _ in range(100000)]


tic()
# インスタンスなし
for text in texts:
    textwrap.wrap(text, width=20)

toc()


# TextWrapperインスタンスの生成
wrapper = textwrap.TextWrapper(width=20)

tic()
# インスタンスあり
for text in texts:
    wrapper.wrap(text)

toc()

実行結果

elapsed time: 1.900254965 [sec]
elapsed time: 1.360962152 [sec]

インスタンス生成と属性代入のコストが無くなるとこれだけ早くなるんですね。

最短3か月でエンジニア転職『DMM WEBCAMP COMMIT』