Pythonで文字列を分割(区切り文字、改行、正規表現、文字数)

Modified: | Tags: 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()の第一引数keependsTrueとすると結果に行末の改行文字を含む。

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()で取得できるので、半分ずつに分割したりもできる。

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

関連カテゴリー

関連記事