文字列を分割する方法(split・splitAt・linesIterator・linesWithSeparatorsメソッド)

Scala 3 (Dotty 0.26.0-RC1) 2.13.3 2.12.12
最終更新:2020年7月6日

[AD] scalapediaでは記事作成ボランティアを募集しています

この記事では、Scalaで文字列を分割する方法をご紹介します。

文字列を分割するには、以下の4つの選択肢があります。使い方は以下のとおりです。

  • split
    • 指定した文字で分割します。
  • splitAt
  • linesIterator
    • 改行文字で区切って文字列をIteratorで返します。各文字列に改行文字は含まれません。
  • linesWithSeparators
    • 改行文字で区切って文字列をIteratorで返します。各文字列に改行文字は含まれます。

それぞれのメソッドの使い方を具体的に見ていきましょう。

splitメソッドの使い方

splitメソッドを使用すると、特定の文字で区切られた文字列を分割することができます。
例えばCSV形式のように、カンマやスペース、タブ文字で区切られた文字列を分割するのに役立ちます。

splitメソッドには4通りの呼び出し方があります。
まず、java.lang.Stringに定義されているのがこの2つです。

Java
public String[] split(String: regexp) public String[] split(String: regexp, Int: limit)

また、scala.collection.StringOpsに定義されているのがこの2つです。

Scala
def split(separator: Char): Array[String] def split(separators: Array[Char]): Array[String]

StringOpsとは、Scalaにおいてjava.lang.Stringを便利に使うことができるラッパークラスです。

次に、それぞれのsplitメソッドを使うサンプルコードを示します。

特定の文字で文字列を分割する

特定の文字によって文字列を分割してみましょう。

文字列を分割する際の区切り文字はChar型で指定します。

Char型ではなくString型、つまり文字列型を指定した場合には、後述の正規表現を引数に取るメソッドを呼び出すことになるので注意してください。
String型であれば1文字でも文字列型です。ご注意ください。
文字列で指定する方法は後ほど説明します。

次のサンプルでは、文字列をカンマ(,)で分割します。
最後の空文字は省略されます。

val str = "1,2,3,4,5," val result = str.split(',') result.zipWithIndex.foreach { case (s, i) => println(s"[${i}] : ${s}") }

実行結果は以下のようになります。
カンマ(,)で分割すると、"1", "2", "3", "4", "5", ""となりますが、最後の空文字は省略されます。

[0] : 1 [1] : 2 [2] : 3 [3] : 4 [4] : 5
Scala Standard Library:split(separator: Char): Array[String]

文字を複数指定して文字列を分割する

複数の文字で分割する場合は、区切り文字をChar型の配列で指定します。
次のサンプルでは、文字列をパイプ(|)またはカンマ(,)のいずれかで分割します。

val str = "2019/12/31 00:00:00|1,2,3,4,5|" val result = str.split(Array('|', ',')) result.zipWithIndex.foreach { case (s, i) => println(s"[${i}] : ${s}") }

実行結果は以下のようになります。
パイプの箇所とカンマの箇所のいずれにおいても分割されていることがわかります。

[0] : 2019/12/31 00:00:00 [1] : 1 [2] : 2 [3] : 3 [4] : 4 [5] : 5

文字列を渡すと正規表現で分割する

前述の文字列をパイプ(|)とカンマ(,)で分割する方法は、正規表現で指定することもできます。
パイプ(|)は、正規表現でエスケープが必要な文字なので、バックスラッシュ(\)でエスケープして指定します。

val str = "2019/12/31 00:00:00|1,2,3,4,5|" val result = str.split("\\||,") result.zipWithIndex.foreach { case (s, i) => println(s"[${i}] : ${s}") }

実行結果は、前述の複数のChar型の値での分割と同様に、以下のようになります。

[0] : 2019/12/31 00:00:00 [1] : 1 [2] : 2 [3] : 3 [4] : 4 [5] : 5

分割上限回数を指定して正規表現で分割する

正規表現で分割する方法では、メソッドの第2引数にパターンの適用回数を指定することができます。

0を指定した場合は、省略した場合と同じです。

val str = "2019/12/31 00:00:00|1,2,3,4,5|" val result = str.split("\\||,", 0) result.zipWithIndex.foreach { case (s, i) => println(s"[${i}] : ${s}") }

実行結果

[0] : 2019/12/31 00:00:00 [1] : 1 [2] : 2 [3] : 3 [4] : 4 [5] : 5

マイナスの値を指定した場合は、結果に最後の空文字も含まれます。

val str = "2019/12/31 00:00:00|1,2,3,4,5|" val result = str.split("\\||,", -1) result.zipWithIndex.foreach { case (s, i) => println(s"[${i}] : ${s}") }

実行結果

[0] : 2019/12/31 00:00:00 [1] : 1 [2] : 2 [3] : 3 [4] : 4 [5] : 5 [6] :

3を指定した場合は、以下のように3つに分割されます。

val str = "2019/12/31 00:00:00|1,2,3,4,5|" val result = str.split("\\||,", 3) result.zipWithIndex.foreach { case (s, i) => println(s"[${i}] : ${s}") }

実行結果

[0] : 2019/12/31 00:00:00 [1] : 1 [2] : 2,3,4,5|

抽出子(Extractor)を使用する

splitは、Array[String]を返しますが、抽出子(Extractor)を使用することで分割した各要素の値を簡単に取り出すことができます。

val str = "Taro Pedia Scala" val Array(firstName, middleName, lastName) = str.split(' ') println(s"First Name : ${firstName}") println(s"Middle Name : ${middleName}") println(s"Last Name : ${lastName}")

実行結果

First Name : Taro Middle Name : Pedia Last Name : Scala

splitAtメソッドの使い方

splitAtメソッドは、文字列のインデックスnの位置で分割したものの前半と後半をタプルで返します。
n番目の文字は前半に入ります。
結果は、val (former, latter) = ...のように受けることで、一度に変数として宣言することができます。

val str = "2019/12/31 00:00:00|1,2,3,4,5" val (former, latter) = str.splitAt(19) println(former) println(latter)

結果は以下のようになります。

2019/12/31 00:00:00 |1,2,3,4,5
Scala Standard Library:splitAt(n: Int): (String, String)

改行文字で区切る方法

linesIteratorメソッドの使い方

linesIteratorメソッドは、文字列を改行文字で区切って、結果をIteratorで返します。
各文字列に改行文字は含まれません。

val str = s"""2019/12/31 00:00:00 1,2,3,4,5 """.stripMargin val result = str.linesIterator result.zipWithIndex.foreach { case (s, i) => println(s"[${i}] : ${s}") }

出力は以下のようになります。 与えた文字列が改行文字によって分割され、1行ずつ処理できているていることがわかります。 出力結果が改行されているのは、printlnメソッドが末尾に付加している改行文字によるものです。

[0] : 2019/12/31 00:00:00 [1] : 1,2,3,4,5
Scala Standard Library:linesIterator: Iterator[String]

また、linesメソッドもlinesIteratorメソッドと同じ働きをします。

ただし、このメソッドはScala 2.13.0で急遽削除されました。
Java 11でStringに追加されたpublic Stream<String> lines()メソッドと競合してしまったためです。
今後はlinesIteratorを使用し、既存の使用箇所も速やかに置き換えましょう。

Scala Standard Library 2.12.12:lines: Iterator[String]

linesWithSeparatorsメソッドの使い方

linesWithSeparatorsメソッドは、文字列を改行文字で区切って、結果をIteratorで返します。
各文字列に改行文字が含まれるのがlinesIteratorメソッドとの違いです。

val str = s"""2019/12/31 00:00:00 1,2,3,4,5""".stripMargin val result = str.linesWithSeparators result.zipWithIndex.foreach { case (s, i) => println(s"[${i}] : ${s}") }

出力は以下のようになります。
結果に改行文字が含まれているので、printlnの改行と相まって1行飛ばしで出力されていることがわかります。

[0] : 2019/12/31 00:00:00 [1] : 1,2,3,4,5
Scala Standard Library:linesWithSeparators: Iterator[String]

サイト内検索


カテゴリ「文字列処理」の記事

文字列をエスケープしたり復元したりする方法(Apache Commons Text) JavaとScalaのString/StringBuilder/StringBuffer使い分け事情 文字列を分割する方法(split・splitAt・linesIterator・linesWithSeparatorsメソッド) trimメソッドで文字列の前後の空白を除去する 文字列が一致するか比較する方法/大文字・小文字を区別せずに比較する方法 特定の文字の文字コード(コード・ポイント)を取得する replaceメソッドなど、文字列を置換する方法を紹介 文字列の先頭や末尾を、取得したり切り落としたりする方法 containsメソッドでStringに特定の文字列が含まれるか調べる方法 数値を文字列に変換する方法 stripメソッドで文字列の前後の全角空白を除去する 文字列を数値に変換するには?to○○メソッドと注意点について 文字列を辞書的に比較する方法/大文字・小文字を区別せずに比較する方法 文字列が特定の文字列で始まるか・終わるかを調べる方法 【getBytes&size】文字列のバイト長を取得する方法 substringでStringを切り取り、部分文字列を抽出する方法 StringOpsとWrappedStringの違いは? 文字列を連結するには?+演算子やString interpolationの使い方 文字列の大文字へ・小文字へ変換する方法 文字列を逆順にする方法 文字列の文字コード(文字セット)を変換する方法 文字列の長さを取得する方法:lengthとcodePointCountの使い分け 文字列をURLエンコード・デコードする方法 文字列が正規表現に合致するか調べる方法 この文字の位置はどこ?文字列のインデックスを取得する方法 文字列をバイト列に、またはバイト列を文字列に変換する方法

カテゴリ「文字列処理」の記事

文字列をエスケープしたり復元したりする方法(Apache Commons Text) JavaとScalaのString/StringBuilder/StringBuffer使い分け事情 文字列を分割する方法(split・splitAt・linesIterator・linesWithSeparatorsメソッド) trimメソッドで文字列の前後の空白を除去する 文字列が一致するか比較する方法/大文字・小文字を区別せずに比較する方法 特定の文字の文字コード(コード・ポイント)を取得する replaceメソッドなど、文字列を置換する方法を紹介 文字列の先頭や末尾を、取得したり切り落としたりする方法 containsメソッドでStringに特定の文字列が含まれるか調べる方法 数値を文字列に変換する方法 stripメソッドで文字列の前後の全角空白を除去する 文字列を数値に変換するには?to○○メソッドと注意点について 文字列を辞書的に比較する方法/大文字・小文字を区別せずに比較する方法 文字列が特定の文字列で始まるか・終わるかを調べる方法 【getBytes&size】文字列のバイト長を取得する方法 substringでStringを切り取り、部分文字列を抽出する方法 StringOpsとWrappedStringの違いは? 文字列を連結するには?+演算子やString interpolationの使い方 文字列の大文字へ・小文字へ変換する方法 文字列を逆順にする方法 文字列の文字コード(文字セット)を変換する方法 文字列の長さを取得する方法:lengthとcodePointCountの使い分け 文字列をURLエンコード・デコードする方法 文字列が正規表現に合致するか調べる方法 この文字の位置はどこ?文字列のインデックスを取得する方法 文字列をバイト列に、またはバイト列を文字列に変換する方法