Pythonで文字列を分割(区切り文字、改行、正規表現、文字数)
Pythonの文字列を、区切り文字、改行、正規表現、文字数で分割するには、split()
, splitlines()
, partition()
, re.split()
やスライスを使う。
文字列の連結や抽出については以下の記事を参照。
区切り文字で分割: split()
区切り文字で分割するには文字列(str
型)のsplit()
メソッドを使う。
デフォルトは空白文字(スペースや改行\n
、タブ\t
など)で分割する。連続する空白文字はまとめて処理される。
戻り値はリスト。
s_blank = 'one two three\nfour\tfive'
print(s_blank)
# one two three
# four five
print(s_blank.split())
# ['one', 'two', 'three', 'four', 'five']
print(type(s_blank.split()))
# <class 'list'>
分割したリストを再び一つの文字列に連結するにはjoin()
を使う。
区切り文字を指定: 引数sep
split()
の第一引数sep
に任意の区切り文字(文字列)を指定できる。
s_comma = 'one,two,three,four,five'
print(s_comma.split(','))
# ['one', 'two', 'three', 'four', 'five']
print(s_comma.split('three'))
# ['one,two,', ',four,five']
複数の異なる区切り文字を指定するには正規表現を使う。後述。
連続する区切り文字はまとめられず、結果のリストに空文字''
が含まれる。文字列の先頭・末尾に区切り文字があるときも、結果に空文字が含まれる。
s_hyphen = '-one--two-'
print(s_hyphen.split('-'))
# ['', 'one', '', 'two', '']
リストから空文字の要素を削除するにはリスト内包表記を使う。空文字は偽と判定される。
print([s for s in s_hyphen.split('-') if s])
# ['one', 'two']
デフォルト(sep
を指定しない場合)は、上述のように連続する空白文字はまとめて分割される。文字列の先頭・末尾に空白があっても結果のリストに空文字は含まれない。sep
に空白文字を指定した場合と挙動が異なるので注意。
s_blank = ' one two three '
print(s_blank.split())
# ['one', 'two', 'three']
print(s_blank.split(' '))
# ['', 'one', 'two', '', 'three', '']
最大分割回数を指定: maxsplit
split()
の第二引数maxsplit
に最大分割回数を指定できる。
最大でmaxsplit
回分割される(結果のリストの要素は最大maxsplit+1
個)。指定した回数を超えると区切り文字があっても分割されない。文字列内の区切り文字の個数を超える値を指定しても問題ない。
s_comma = 'one,two,three,four,five'
print(s_comma.split(',', 2))
# ['one', 'two', 'three,four,five']
print(s_comma.split(',', 10))
# ['one', 'two', 'three', 'four', 'five']
区切り文字で右から分割: rsplit()
split()
は左から分割するが、rsplit()
は右から分割する。使い方はsplit()
と同じ。
第二引数maxsplit
に最大分割回数を指定したときsplit()
と結果が異なる。
s_comma = 'one,two,three,four,five'
print(s_comma.rsplit(','))
# ['one', 'two', 'three', 'four', 'five']
print(s_comma.rsplit(',', 2))
# ['one,two,three', 'four', 'five']
print(s_comma.rsplit(',', 10))
# ['one', 'two', 'three', 'four', 'five']
改行で分割: splitlines()
改行で分割するには文字列(str
型)のsplitlines()
メソッドを使う。
split()
やrsplit()
はデフォルトで改行を含む空白文字で分割し、引数sep
に改行文字を指定することもできるが、改行で分割するにはsplitlines()
のほうが便利。
例えば、Macを含むUnix系OSで使われる改行文字\n
(LF)とWIndows系OSで使われる改行文字\r\n
(CR+LF)が混在して、末尾にも改行文字がある文字列の場合。
s_lines_multi = '1 one\n2 two\r\n3 three\n'
print(s_lines_multi)
# 1 one
# 2 two
# 3 three
#
split()
をデフォルトで適用すると改行文字だけでなくスペースでも分割される。
print(s_lines_multi.split())
# ['1', 'one', '2', 'two', '3', 'three']
引数sep
には単独の改行文字しか指定できないので、改行文字が混在していると対応できない。また末尾の改行文字でも分割される。
print(s_lines_multi.split('\n'))
# ['1 one', '2 two\r', '3 three', '']
splitlines()
だと、各種の改行文字で分割するが、ほかの空白文字では分割しない。
print(s_lines_multi.splitlines())
# ['1 one', '2 two', '3 three']
splitlines()
の第一引数keepends
をTrue
とすると結果に行末の改行文字を含む。
print(s_lines_multi.splitlines(True))
# ['1 one\n', '2 two\r\n', '3 three\n']
そのほか改行に関する処理は以下の記事を参照。
区切り文字と前後に三分割: partition(), rpartition()
区切り文字とその前後の部分に三分割するには文字列(str
型)のpartition()
メソッドを使う。
split()
などと異なり、リストではなくタプルを返す。区切り文字自体も含まれる。
s = 'abc@xyz'
print(s.partition('@'))
# ('abc', '@', 'xyz')
print(type(s.partition('@')))
# <class 'tuple'>
指定した区切り文字が無い場合や、先頭・末尾にある場合は、結果のタプルに空文字''
が含まれる。
print(s.partition('123'))
# ('abc@xyz', '', '')
print(s.partition('abc'))
# ('', 'abc', '@xyz')
print(s.partition('xyz'))
# ('abc@', 'xyz', '')
指定した区切り文字が複数含まれる場合、partition()
は最初(左側)の出現位置で区切る。最後(右側)の出現位置で区切るにはrpartition()
を使う。
s = 'abc@xyz@123'
print(s.partition('@'))
# ('abc', '@', 'xyz@123')
print(s.rpartition('@'))
# ('abc@xyz', '@', '123')
区切り文字が一つしか含まれていない場合はpartition()
とrpartition()
は同じ結果を返す。
正規表現にマッチした部分で分割: re.split()
split()
は引数sep
に指定した区切り文字に完全一致した箇所で分割する。完全一致ではなく正規表現にマッチした文字列で分割するにはreモジュールのsplit()
関数を使う。
標準ライブラリのreモジュールをインポートして使う。標準ライブラリなので追加のインストールは不要。
re.split()
では第一引数に正規表現パターン、第二引数に対象の文字列を指定する。split()
と同様に、第三引数maxsplit
に最大分割回数を指定することもできる。
連続する数字で分割する例。
import re
s_nums = 'one1two22three333four'
print(re.split(r'\d+', s_nums))
# ['one', 'two', 'three', 'four']
print(re.split(r'\d+', s_nums, 2))
# ['one', 'two', 'three333four']
reモジュールのその他の関数、正規表現オブジェクトの生成方法などは以下の記事を参照。
複数の異なる区切り文字で分割
正規表現に詳しくなくても覚えておくと便利なのが以下の2つ。
大括弧[]
で囲むとその中の任意の一文字にマッチする。複数の異なる区切り文字(一文字)で分割したい場合に使う。
s_marks = 'one-two+three#four'
print(re.split('[-+#]', s_marks))
# ['one', 'two', 'three', 'four']
パターンを|
で区切るといずれかのパターンにマッチする。各パターンには正規表現の特殊文字を使うことももちろん可能だが、文字列をそのまま指定してもよい。複数の異なる区切り文字(文字列)で分割したい場合に使う。
s_strs = 'oneXXXtwoYYYthreeZZZfour'
print(re.split('XXX|YYY|ZZZ', s_strs))
# ['one', 'two', 'three', 'four']
文字数で分割: スライス
文字数で分割する場合はスライスを使う。
s = 'abcdefghij'
print(s[:5])
# abcde
print(s[5:])
# fghij
分割した文字列をタプルとして取得したり、それぞれ変数に代入したりできる。
s_tuple = s[:5], s[5:]
print(s_tuple)
# ('abcde', 'fghij')
print(type(s_tuple))
# <class 'tuple'>
s_first, s_last = s[:5], s[5:]
print(s_first)
# abcde
print(s_last)
# fghij
3分割でも同様。
s_first, s_second, s_last = s[:3], s[3:6], s[6:]
print(s_first)
# abc
print(s_second)
# def
print(s_last)
# ghij
文字数は組み込み関数len()
で取得できるので、半分ずつに分割したりもできる。
- 関連記事: Pythonで文字列の長さ(文字数)を取得
half = len(s) // 2
print(half)
# 5
s_first, s_last = s[:half], s[half:]
print(s_first)
# abcde
print(s_last)
# fghij
連結したい場合は+
演算子を使う。
print(s_first + s_last)
# abcdefghij