すでにメンバーの場合は

無料会員登録

GitHubアカウントで登録 Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

登録がまだの方はこちらから

Pikawakaにログイン

GitHubアカウントでログイン Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

Ruby

【Ruby】 splitメソッドの使い方-基礎から応用を理解しよう

ぴっかちゃん
ぴっかちゃん

splitメソッドとは、文字列を指定した区切り文字で分割し、配列で返すメソッドです。splitメソッドの第一引数に区切り文字を指定し、第二引数に分割数を指定する事が出来ます。

splitメソッドを使えば、以下のコードのように文字列をカンマ(,)で分割し、その分割した文字列を要素とした配列で取得する事が出来ます。

irb | splitメソッドのサンプルコード
1
2
irb(main):001:0> "Apple,Orange,Cherry,Banana".split(',')
=> ["Apple", "Orange", "Cherry", "Banana"]

splitメソッドに指定する事が出来る区切り文字には、split(',')のように文字列だけではなく正規表現もあります。

splitメソッドは、文字列を指定した区切り文字で分割して配列にしたい場合にとても便利なメソッドなので、是非マスターしていきましょう。

splitメソッドの基本的な使い方

この章では、豊富なサンプルコードを用いて以下を詳しく解説します。

  1. 基本構文
  2. 指定できる区切り文字の種類
  3. 分割する回数を制限する方法

基本構文

以下のコードのように、splitメソッドの「第一引数には区切り文字」を指定し、「第二引数には分割数」を指定します。

splitメソッドの基本構文 -->
1
2
# split([sep[, limit]])
"文字列".split(区切り文字, 分割数)

例えば、以下のコードのようにsplitメソッドに区切り文字(':')だけ指定すると、文字列を区切り文字(':')で全て分割して配列で返します。

irb | splitメソッドに区切り文字だけ指定した場合
1
2
irb(main):001:0> "Tokyo:Saitama:Okinawa".split(':')
=> ["Tokyo", "Saitama", "Okinawa"] # 配列の要素は3つある

しかし、splitメソッドの第二引数に分割数(2)を指定すると、以下のコードのように指定された数の分割しか行いません。

irb | splitメソッドに分割数も指定した場合
1
2
irb(main):002:0> "Tokyo:Saitama:Okinawa".split(':', 2)
=> ["Tokyo", "Saitama:Okinawa"] # 2分割に制限され要素は2つになる

文字列の後半のSaitama:Okinawaにもコロンはありますが、文字列の左側からコロンを探すのでTokyo:Saitamaのコロンで2分割されます。

irb | 配列にsplitメソッドを使用した場合
1
2
irb(main):003:0> ["Tokyo", "Saitama:Okinawa"].split(',')
NoMethodError (undefined method `split' for ["Tokyo", "Saitama:Okinawa"]:Array)

また、splitメソッドはStringクラスのメソッドなので、上記のコードのようにString以外に使用するとエラーになるので注意してください。

区切り文字の種類

splitメソッドの第一引数に指定する事が出来る区切り文字には、文字列以外にもnil、1バイトの空白文字、正規表現があります。

splitメソッドにこの区切り文字を指定すると、どんな分割が可能になるのかそれぞれの特徴を掴んでいきましょう。

文字列

区切り文字に文字列を指定すると、その文字列に一致する部分で分割されます。

irb | 区切り文字に文字列を指定した場合
1
2
3
4
5
irb(main):001:0>"Apple&Orange&Cherry&Banana".split('&')
=> ["Apple", "Orange", "Cherry", "Banana"] 

irb(main):002:0> "AppleAndOrangeAndCherryAndBanana".split('And')
=> ["Apple", "Orange", "Cherry", "Banana"]

正規表現を使う

splitメソッドの区切り文字には、正規表現を指定する事が出来ます。文字列は、正規表現に一致する部分で分割されます。

区切り文字に正規表現を使った場合-->
1
"文字列".split(/正規表現/)

以下のコードのように文字列をカンマ(,)に一致する部分で分割したい場合は、区切り文字を文字列にしたsplit(',')でも実現出来ますね。

irb | カンマに一致する部分で分割したい場合
1
2
irb(main):001:0> "10:30,15:10".split(',')
=> ["10:30", "15:10"]

ただ"10:30,15:10"をカンマだけではなく、カンマ(,) コロン(:)、それぞれの区切り文字で文字列を分割したい場合には、以下のコードのように区切り文字に正規表現を指定する事で実現する事が出来ます

irb | カンマとコロンの両方に一致する部分で分割したい場合
1
2
irb(main):002:0> "10:30,15:10".split(/[:|,]/)
=> ["10", "30", "15", "10"]

このように区切り文字に正規表現を使うことで、柔軟に文字列を分割する事が出来ます。

1バイトの空白文字

1バイトの空白文字とは、以下のコードのようにsplitメソッドの区切り文字に、文字列の半角スペース' 'を指定します。

1バイトの空白文字(' ')を区切り文字に指定した場合-->
1
"文字列".split(' ')

このようにすると、以下のコードのように「その文字列の先頭と末尾の空白文字」を除いてくれ、その上で「空白文字に一致する部分」で分割します。

irb | 1バイトの空白文字で区切る場合
1
2
irb(main):001:0> " abc def g ".split(' ')
=> ["abc", "def", "g"]

文字列に半角スペースが含まれる例

上記の文字列の空白文字は半角スペースにしていますが、この文字列の「先頭と末尾を除外する空白文字」や「分割する対象の空白文字」は、以下のコードのように半角のスペースだけではなく、改行(\n)、タブ(\t)も対象となります。

irb | 文字列に改行やタブが含まれる場合
1
2
3
4
5
irb(main):002:0>  "\nabc\ndef\ng\n".split(' ')
=> ["abc", "def", "g"]

irb(main):003:0>  "\tabc\tdef\tg\t".split(' ')
=> ["abc", "def", "g"]

文字列に改行やタブが含まれる例

このようにsplit(' ')の区切り文字を指定すると、文字列に含まれる半角スペース、改行、タブを空白文字として、その文字列の先頭と末尾の空白文字の除外と空白文字に一致する部分で分割されます。

また、注意点として全角スペースは空白文字の対象外です。

irb | 文字列のスペースを全て全角スペースにした場合
1
2
irb(main):004:0> " abc def g ".split(' ')
=> [" abc def g "]

文字列に全角スペースが含まれる場合

上記のコードのように全角スペースが含まれた文字列にsplit(' ')を実行しても、前後の全角スペースが除外されたり、全角スペースに一致する部分で分割されることはないので注意してください。

1バイトの区切り文字を指定した場合
  • 文字列の先頭と末尾の空白文字は除かれる
  • 文字列の空白文字の部分で分割される
  • split(' ')で対象となる文字列中の空白文字は、半角スペース、改行、タブの3つある

nil

区切り文字にnilを指定した場合は、以下のように記述します。

nilを区切り文字に指定した場合-->
1
"文字列".split(nil)

区切り文字にnilを指定すると、以下のコードのように「その文字列の先頭と末尾の空白文字」を除いてくれ、その上で「空白文字に一致する部分」で分割します。

irb | nilで区切り文字を指定した場合
1
2
irb(main):001:0> " abc def g ".split(nil)
=> ["abc", "def", "g"]

これは、先ほど解説したsplit(' ')の1バイトの空白文字を指定した場合と同じです。また、文字列の「先頭と末尾を除外する空白文字」や「分割する対象の空白文字」も同様に半角スペース、改行、タブが対象となります。

irb | 改行やタブが含まれる文字列にsplit(nil)を実行する場合
1
2
3
4
5
irb(main):002:0>  "\nabc\ndef\ng\n".split(nil)
=> ["abc", "def", "g"]

irb(main):003:0>  "\tabc\tdef\tg\t".split(nil)
=> ["abc", "def", "g"]

更には、以下のコードのようにsplitメソッドの引数を省略した場合もsplit(nil)split(' ')と同じ結果になります。

irb | 3つの区切り文字の結果
1
2
3
4
5
6
7
8
irb(main):004:0> " abc def g ".split(nil)
=> ["abc", "def", "g"]

irb(main):005:0> " abc def g ".split(' ')
=> ["abc", "def", "g"] # split(nil)と同じ

irb(main):006:0> " abc def g ".split 
=> ["abc", "def", "g"] # split(nil)と同じ

つまり、上記のコードの3つとも「その文字列の先頭と末尾の空白文字」を除いてくれ、その上で「空白文字に一致する部分」で分割します。

そして、空白文字とは半角スペース改行タブが対象となります。

分割数の制限

splitメソッドの第二引数に分割数を指定する事で、区切り文字に一致する部分の分割数を制限する事が出来ます。

splitメソッドの基本構文 -->
1
2
# split([sep[, limit]])
"文字列".split(区切り文字, 分割数)

例えば、以下のコードのように第二引数に2を指定すると、指定した区切り文字(',')に一致する最初の部分で2分割します。

irb | 2分割に制限する場合
1
2
irb(main):001:0> "abc,def,g,hi".split(',', 2)
=> ["abc", "def,g,hi"] # 2分割になる

3分割に制限する場合は、以下の通りになります。

irb | 3分割に制限する場合
1
2
irb(main):002:0> "abc,def,g,hi".split(',', 3)
=> ["abc", "def", "g,hi"] # 3分割になる

分割数に0を指定した場合

分割数に0を指定した場合は、分割数の制限なく区切り文字に一致する全ての部分で分割します。

irb | 分割数を0に指定した場合
1
2
irb(main):001:0> "abc,def,g,hi".split(',', 0)
=> ["abc", "def", "g", "hi"] # カンマに一致する全ての部分で分割する

そして、以下のコードのように分割数の制限がなく0に指定する場合は、第二引数を指定せずに省略が出来ます。

irb | 第二引数を省略した場合
1
2
3
# "abc,def,g,hi".split(',', 0)と同じ
irb(main):002:0> "abc,def,g,hi".split(',')
=> ["abc", "def", "g", "hi"] # カンマsplitメソッドの返り値は、区切り文字で一致した部分を分割した配列です。に一致する全ての部分で分割する

また、",,,abc,def,g,hi"の文字列に対してsplit(',')を実行すると、以下のコードのように配列の要素が空になる場合でも分割されます。

irb | 配列の要素が空になる場合でも分割される場合
1
2
irb(main):003:0> ",,,abc,def,g,hi".split(',')
=> ["", "", "", "abc", "def", "g", "hi"]

しかし、"abc,def,g,hi,,,"の文字列に対してsplit(',')を実行すると、["abc", "def", "g", "hi", "", "", ""]とはならず、以下のコードのように末尾の場合だけ空の配列要素は作成されません。

irb | 末尾の場合は、空の配列要素は作成されない
1
2
3
irb(main):004:0> "abc,def,g,hi,,,".split(',')
=> ["abc", "def", "g", "hi"]
 # ["abc", "def", "g", "hi", "", "", ""] にはならない

上記のコードのように配列末尾の空文字列は除外されます。

分割数の制限が必要な場合

無駄に分割する必要がない場合には、第二引数に分割数を指定し制限します。

例えば、以下のコードはカンマに一致する全ての部分で分割されますが(["abc", "def", "g"])、その後のfirstメソッドで分割された最初の"abc"の要素だけ取得しています。

分割数の制限が必要な場合
1
2
irb(main):001:0> first = "abc,def,g".split(',').first
=> "abc" # 分割した最初の要素しか使わない

分割された最初の要素だけ必要なので、他の箇所すべてを分割していく必要はないですよね。このように無駄に分割する必要がない場合には、以下のコードのように分割数を指定して制限してあげます。

irb | 2分割に制限をする
1
2
3
irb(main):002:0> first = "abc,def,g".split(',', 2).first
=> "abc"
# "abc,def,gi".split(',', 2)は ["abc", "def,g"] の2分割に制限される

区切り文字に一致する部分すべてを分割していく必要がない場面では、分割数の制限をして無駄な処理を行わないようにしましょう。

ポイント
  1. splitメソッドの第二引数を指定すると、分割数を制限する事が出来る
  2. 分割数に0を指定した場合は、splitの第二引数を指定しない場合と同じ挙動になる
  3. 区切り文字に一致する部分すべてを分割する必要がない場合は、分割数の制限をする

splitメソッドの応用的な使い方

この章では、文字列を分割する際に良く使われるsplitメソッドとmapメソッドの応用的な使い方を解説します。また、splitメソッドを使う際の注意点も確認していきます。

mapメソッドと組み合わせる

splitメソッドの返り値は、文字列に対して指定した区切り文字で分割した配列です。この配列に対してmapメソッドを使えば、各要素を簡単に加工する事が出来ます。

splitメソッドとmapメソッドの組み合わせ -->
1
"文字列".split(区切り文字, 分割数).map { |変数| 実行する処理 }

mapメソッドは、配列の要素の数だけブロック内で実行される処理を繰り返して新しい配列を返すメソッドです。mapメソッドの詳細は「mapメソッドの使い方」を参考にしてください。

分割した配列の要素を文字列から数値に変換

カンマ区切りの数字の文字列を数値に変換した配列が欲しい!と言う場合に、mapメソッドと組み合わせる事で簡単に実現出来ます。

例えば、以下のコードのようにカンマ区切りの数字の文字列にsplit(',')を実行すると、カンマに一致する部分で分割されて配列になりますが、各配列の要素は文字列です。

irb | 数字の文字列をsplitメソッドで分割した場合
1
2
3
4
5
6
irb(main):002:0> num_array = "1,2,55,6,9,3".split(',')
=> ["1", "2", "55", "6", "9", "3"]
irb(main):003:0> num_array[0]
=> "1" # 配列の最初の要素
irb(main):004:0> num_array[0].class
=> String # 要素が文字列だと分かる

ここでは文字列ではなく、数値に変換された要素が欲しいですよね。
mapメソッドを組み合わせると、以下のコードのように各要素が数値に変換された配列を取得する事が出来ます。

irb | mapメソッドと組み合わせて各要素を数値にした配列を取得する
1
2
3
4
5
6
irb(main):005:0> num_array = "1,2,55,6,9,3".split(',').map{|n| n.to_i}
=> [1, 2, 55, 6, 9, 3]
irb(main):006:0> num_array[0]
=> 1  # 配列の最初の要素
irb(main):007:0> num_array[0].class
=> Integer # 要素が数値だと分かる

上記のコードは「split(',')で分割された文字列の各要素」をmapメソッドのブロック変数nに渡し、to_iメソッドで数値に変換しています。要素の数だけ繰り返し処理が実行されて、各要素を数値に変換した新たな配列を返します。

また、以下のコードのように条件が揃えば&:メソッド名のように省略して記述することが出来ます。(詳細はmapメソッドの省略した書き方へ)

irb | 条件が揃った中での省略した書き方
1
2
3
4
5
6
irb(main):008:0> "1,2,55,6,9,3".split(',').map{|n| n.to_i}
=> [1, 2, 55, 6, 9, 3]

# 省略した書き方
irb(main):009:0> "1,2,55,6,9,3".split(',').map(&:to_i)
=> [1, 2, 55, 6, 9, 3]

今回は、to_iメソッドで各要素の文字列を数値に変換する方法を解説しましたが、用途に合わせた要素の加工を試してみてください。

注意点

splitメソッドを使用する際に、文字列を変換するために無理やり使っていないか、目的にあったメソッドを使用できているかという点に注意してください。

splitメソッドの返り値は、配列です。「文字列を区切り文字に一致する部分で分割し、配列として取得したい場合」に使用されるメソッドですね。

irb | splitメソッドの使用例
1
2
irb(main):001:0> "abc,def,g".split(',')
=> ["abc", "def", "g"] # 返り値は配列

しかし、以下のコードのように「文字列の区切り文字をカンマ,からコロン:に置き換える目的」で「文字列→配列→文字列」と変換している場合は注意が必要です。

irb | 文字列のカンマをコロンに置き換える
1
2
irb(main):002:0>  "abc,def,g".split(',').join(':')
=> "abc:def:g"

上記のコードは、最終的に文字列にしているので、わざわざ配列を経由する必要がありません。文字列を置き換えるのが目的の場合は、以下のコードのようにsplitメソッドではなくgsubメソッドを使うべきです。

irb | 文字列を置き換える為にgsubメソッドを使う
1
2
irb(main):003:0> "abc,def,g".gsub(',', ':')
=> "abc:def:g"

splitメソッドは、特定の区切り文字で文字列を分割する事が出来る便利なメソッドですが、返り値は配列です。その配列を使用して別の処理を行うことは良くありますが、今回のような文字列の置換が目的の場合は、splitメソッドを無理やり使うのではなく、目的に合った他のメソッドがないか考えるようにしましょう。

この記事のまとめ

  • splitメソッドは、文字列を指定した区切り文字で分割し、配列で返すメソッド
  • 第一引数に区切り文字を指定し、第二引数に分割数を指定する事が出来る
  • 区切り文字は、文字列以外にもnil、1バイトの空白文字、正規表現を指定出来る