note.nkmk.me

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

Date: 2018-05-31 / tags: Python, 文字列操作, 正規表現

Pythonの文字列を区切り文字、改行、正規表現、文字数で分割する方法を説明する。

  • 区切り文字で分割: split()
  • 区切り文字で右から分割: rsplit()
  • 改行で分割: splitlines()
  • 正規表現にマッチした部分で分割: 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'>

第一引数sepで区切り文字を指定

第一引数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']

複数の区切り文字を指定したい場合は正規表現を使う。後述。

また、この例では問題ないが、区切り文字で分割した結果の前後に空白が生じる場合の対処は以下の記事を参照。

第二引数maxsplitで最大分割回数を指定

第二引数maxsplitで最大分割回数を指定できる。

指定した回数を超えると区切り文字があっても分割されない。

print(s_comma.split(',', 2))
# ['one', 'two', 'three,four,five']

例えば最初の行を削除した文字列を取得したい場合に便利。

sep='\n', maxsplit=1とすると最初の改行文字\nでのみ分割され、最初の改行文字\nで二分割された文字列のリストが取得できる。このリストの2つ目の要素[1]が最初の行を除いた文字列となる。最後の要素なので[-1]と指定することも可能。

s_lines = 'one\ntwo\nthree\nfour'
print(s_lines)
# one
# two
# three
# four

print(s_lines.split('\n', 1))
# ['one', 'two\nthree\nfour']

print(s_lines.split('\n', 1)[0])
# one

print(s_lines.split('\n', 1)[1])
# two
# three
# four

print(s_lines.split('\n', 1)[-1])
# two
# three
# four

同様に、はじめの2行を削除した文字列は以下のように取得できる。

print(s_lines.split('\n', 2)[-1])
# three
# four

区切り文字で右から分割: rsplit

文字列(str型)のrsplit()メソッドはsplit()の右から分割するバージョン。

第二引数maxsplitで最大分割回数を指定したときのみsplit()と結果が異なる。

split()の例と同様の考え方で、最後の行を削除した文字列を取得したい場合はrsplit()を使う。

print(s_lines.rsplit('\n', 1))
# ['one\ntwo\nthree', 'four']

print(s_lines.rsplit('\n', 1)[0])
# one
# two
# three

print(s_lines.rsplit('\n', 1)[1])
# four

終わりの2行を削除した文字列は以下のように取得できる。

print(s_lines.rsplit('\n', 2)[0])
# one
# two

改行で分割: 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']

第一引数keependsTrueとすると結果に行末の改行文字を含む。

print(s_lines_multi.splitlines(True))
# ['1 one\n', '2 two\r\n', '3 three\n']

そのほか改行に関する処理は以下の記事を参照。

正規表現にマッチした部分で分割: re.split

split()rsplit()では引数sepの区切り文字に完全一致した場合に分割される。

完全一致ではなく正規表現にマッチした文字列で分割したい場合はreモジュールのsplit()関数を使う。

標準ライブラリのreモジュールをインポートして使う。標準ライブラリなので追加のインストールは不要。

re.split()では第一引数に正規表現パターン、第二引数に対象の文字列を指定する。

連続する数字で分割する例。

import re

s_nums = 'one1two22three333four'

print(re.split('\d+', s_nums))
# ['one', 'two', 'three', 'four']

第三引数maxsplitに最大分割回数を指定可能。

print(re.split('\d+', s_nums, 2))
# ['one', 'two', 'three333four']

reモジュールのその他の関数、正規表現オブジェクトの生成方法などは以下の記事を参照。

複数の異なる区切り文字で分割

正規表現に詳しくなくても覚えておくと便利なのが以下の2つ。

大括弧[]で囲むとその中の任意の一文字にマッチする。複数の異なる区切り文字(一文字)で分割させたい場合に使う。

s_marks = 'one-two+three#four'

print(re.split('[-+#]', s_marks))
# ['one', 'two', 'three', 'four']

パターンを|で区切るといずれかのパターンにマッチする。各パターンには正規表現の特殊文字を使うことももちろん可能だが、文字列をそのまま指定してもOK。複数の異なる区切り文字(文字列)で分割させたい場合に使う。

s_strs = 'oneXXXtwoYYYthreeZZZfour'

print(re.split('XXX|YYY|ZZZ', s_strs))
# ['one', 'two', 'three', 'four']

文字列のリストを連結

これまでの例では文字列を分割してリストを取得した。

文字列のリストをひとつの文字列に連結したい場合は文字列メソッドのjoin()を使う。

'間に挿入する文字列'join()メソッドを呼び出し、引数として連結したい文字列のリストを渡す。

l = ['one', 'two', 'three']

print(','.join(l))
# one,two,three

print('\n'.join(l))
# one
# two
# three

print(''.join(l))
# onetwothree

文字列の連結についての詳細は以下の記事を参照。

文字数で分割: スライス

文字数で分割する場合はスライスを使う。

スライスについての詳細は以下の記事を参照。

以下のように分割できる。

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
スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事