2021.10.12
2023.08.16
Fabeee社員ブログ
こんにちは!Fabeeeのエンジニア、凛子です。
今回のトピックはPythonで文字列を分割する方法です。
処理を書いていると文字列を分割したくなる時があると思います。
そんな時に使える技をご紹介していきます。
目次
文字列を区切り文字で分割する
例えば電話番号をハイフンで分割する場合を考えてみましょう。
# ハイフンで区切る
tel = '03-1111-2222'
tel.split('-')
# -> ['03', '1111', '2222']
このようにして分割することができます。
Pythonのstr型にはsplit()メソッドが用意されているのでこれを使います。
戻り値はstrの配列です。
引数には区切り文字を指定します。
この区切り文字を指定しない場合は、空白(全角半角スペース、改行(\n, \r\n)、タブ(\t))で区切られます。
# @で区切る
email = 'mail@test.co.jp'
email.split('@')
# -> ['mail', 'test.co.jp']
# 区切り文字を指定しない=空白で区切られる
text = '今日は いい 天気です。'
text.split()
# -> ['今日は', 'いい', '天気です。']
# 連続した空白はまとめて区切られる
text2 = '先週末に\n\n海へ\t\tドライブに 行きました。'
# -> ['先週末に', '海へ', 'ドライブに', '行きました。']
このsplit()メソッドでは区切り文字はひとつしか使うことができません。
では複数の区切り文字で分割したい場合はどのようにしたらよいでしょうか?
正規表現で分割する
複数の区切り文字で分割したい場合は、正規表現を使って分割できるreモジュールのsplit()関数を使います。
re.split()関数は引数を3つとります。
第一引数:正規表現パターン
第二引数:分割したい文字列
第三引数:最大分割回数(未指定でもOK)
import re
email = 'tanaka-satoshi-0123@test.co.jp'
re.split('-|@', email) # -|@ = -もしくは@
# -> ['tanaka', 'satoshi', '0123', 'test.co.jp']
# 最大分割回数を指定
re.split('-|@', email, 1)
# -> ['tanaka', 'satoshi-0123@test.co.jp']
# 先頭から1回分割され、以降は分割されない
X文字ずつ分割する
では区切り文字ではなく、2文字ずつなど文字数で分割したい場合はどうでしょう。
正規表現とスライスを組み合わせることでも実現することができます。
# 2文字ずつ分割
text = 'インドカレーが食べたいです。'
re.split('(..)', text)[1::2]
# -> ['イン', 'ドカ', 'レー', 'が食', 'べた', 'いで', 'す。']
上記の例ではどのようなことが行われているのでしょうか。ひとつずつみていきましょう。
まず正規表現でsplitしている re.split(‘(..)’, text) この部分です。
「ふたつの連続した文字(..)」の正規表現を使って2文字ずつ分割しています。
正規表現で.は任意の一文字を表します。何でもよいから何か一文字、ということですね。
re.split('(..)', text)
# -> ['', 'イン', '', 'ドカ', '', 'レー', '', 'が食', '', 'べた', '', 'いで', '', 'す。', '']
このままでは間に空文字が入ってしまっていますね。
これをスライスを用いて抜いているのがこの部分[1::2]です。
ところでスライスとは何でしょうか?
スライスとは?
week_days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
week_days[2:5]
# -> ['Wednesday', 'Thursday', 'Friday']
このように、スライスを使うと配列を指定した範囲で切り出すことができます。
開始位置と終了位置を[開始位置:終了位置]のように指定します。
開始位置、終了位置はどちらか一方のみを指定することもできます。
# 開始位置のみ指定
week_days[2:]
# -> ['Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
# 終了位置をしていしていないため配列の末尾まで含まれる
# 終了位置のみ指定
week_days[:5]
# -> ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
# 開始位置を指定していないため配列の先頭から含まれる
またスライスは増分も指定することができます。
[開始位置:終了位置:増分]
week_days[::2]
# -> ['Monday', 'Wednesday', 'Friday', 'Sunday']
# 1つおきに取得される
増分という言葉がわかりにくいですが、「x個おきに」というようなイメージですね。
さて、文字列を2文字ずつ分割する話に戻りますと
これらのことを使って
text = 'インドカレーが食べたいです。'
split_text = re.split('(..)', text)
split_text
# -> ['', 'イン', '', 'ドカ', '', 'レー', '', 'が食', '', 'べた', '', 'いで', '', 'す。', '']
split_text[1::2]
# -> ['イン', 'ドカ', 'レー', 'が食', 'べた', 'いで', 'す。']
このように分割することができます。
おわりに
ここまで文字列を分割するいくつかの方法を紹介してきました。
いかがでしたでしょうか。
ぜひぜひ日々のプログラミングにお役立てください!