Posted at

猿でも分かるScala!:文字列の扱い

More than 5 years have passed since last update.


はじめに

何らかのプログラミング言語を利用すると、文字列の操作は数値の処理と同じくらい頻繁に現れます。そこで、猿でも分かるScala!シリーズの本記事ではScala言語の文字列の基本操作を紹介します。紹介する内容は主に以下の項目になります。


  • Stringオブジェクトの生成

  • エスケープ文字

  • 生文字リテラル

  • 文字列の連結、検索、抽出、置換

  • 生文字リテラルと正規表現

それでははじめましょう!


Stringオブジェクトの生成

Scala言語で文字列を扱うとき、最も基本的な操作は文字列をオブジェクトとして生成することです。Stringオブジェクトを生成する場合はダブルクオーテーション記号"で文字列を囲みます。例えばStringオブジェクトtextを生成したい場合には次のようにします。

val str:String = "test"


エスケープ文字

Scalaは他の言語と同じようにエスケープ文字を持ちます。エスケープ文字は次のようになっています。

識別
説明
使用例

\n
改行コード(LF)
Hello\n

\r
改行コード(CR)
Hello\r

\t
タブ文字
\tHello

\b
後退文字
Hello\b\b

\ \
バックスラッシュ
\ \ ([a-z]+\ \ )

\'
シングルクオーテーション
\'Hello\'

\"
ダブルクオーテーション
\"Hello\"


生文字リテラル

生文字リテラルはダブルクオーテーション記号を3つつなげた"""で囲んだ文字列です。生文字リテラルは


  • エスケープ文字を持たない。したがって\をテキスト内で自由に使うことができます。

  • 改行コードをそもまま使うことが可能になり、複数行の文字列を記述できます。

例えば生文字リテラルを次のように生成することができます。

val test = """This is a pen.

My name is Tom.
Thank you \
"""

生文字リテラルは後で正規表現と一緒に再度紹介します。


文字列の連結:+

文字列の結合には演算子+を使います。具体的に"Thank"と"you"を結合してみましょう。結合は次のように行います。

val str1 = "Thank"

val str2 = "you"
val str3 = str1 + str2

ここでは"Thank"オブジェクトと"you"オブジェクトが生成され、その後でこれら2つのオブジェクトの連結処理が行われ新たな"Thankyou"オブジェクトが生成されています。ここで生成された変数にはvalが付いているので、生成されたStringオブジェクトは不変オブジェクトになります。したがって文字列str1str2はそのままの状態で、新しい"Thankyou"オブジェクトが生成されています。


メソッドとしての+

演算子+はStringオブジェクトの+メソッドでもあります。したがって次のようにも文字列結合処理を書くことが可能です。

val str4 = str1.+(str2)


検索:indexOf

StringのindexOfメソッドはあるStringの文字列の中に指定の文字が文字列の左から数えて何番目に存在するか、その位置を教えてくれるメソッドです。文字の位置は文字列の左端を0番目として、そこから何番目に存在しているのか表示されます。

例えば

val index:Int = "Thankyou".indexOf("o")

では"o"の位置が6と表示されます。


抽出:indexOf, lastIndexOf, substring

文字列を抽出するためにすでに紹介したindexOfに加えて、lastIndexOfsubstringを紹介します。

indexOfは左から指定の文字が存在するか調べるのに対して、lastIndexOfは右端から検索してインデックスを返します(インデックスは左端の0から数えられます)。例えば文字列"2014-06-06"の右側のハイフンのインデックスを調べます。

val index2:Int = "2014-06-06".lastIndexOf("-")

この処理でインデックスとして7が返ってきます。ちゃんと2番目の"-"のインデックスを取得出来ました。それでは次に2つのハイフンで挟まれている"06"を抽出してみましょう。これを実行するためにsubstringメソッドを使います。substring(x,y)で インデックスxから インデックスy-1までの文字列を抽出します。実際にやってみましょう。

val index3:Int = "2014-06-06".substring(4+1, 7)


置換:replace

文字列の置換をするにはreplaceメッソドを使います。例えば"2014-06-07"の"06"を"08"で置換することを考えます。これは次の処理で可能です。

val rep = "2014-06-07".replace("06", "08")

注意点としては置換でヒットした文字は全て置き換えられてしまう点です。例えば

val rep2 = "2014-06-06".replace("06", "07")

で置換した場合には帰ってくる結果が2014-07-07となります。


生文字リテラルと正規表現

Scalaで正規表現を使用するときに生文字リテラルが便利になってきます。例として2014-06-07から06を抽出する正規表現を考えてみましょう。正規表現は生文字リテラルを使って次のようになります。

val regex = """\d\d\d\d-(\d\d)-\d\d""".r

ここで


  • \dは数字1文字を表しています。

  • \d\d\d\d-(\d\d)-\d\dは数字4つ続き、その後にハイフン、その後に数字2つ続きでこの2つを抽出、更にその後にハイフンと数字2つ続くという意味。「()」は抽出対象を意味しています。

正規表現(regex)オブジェクトとは「.r」で生成されます。生文字リテラルを使うと通常の文字列の中でエスケープ文字として扱われるバックスラッシュ\を気にすることなく正規表現を記述できます。

定義した正規表現を使って"2014-06-07"から06を抽出して変数xに格納してみます。これは次のような処理で実行できます。

val regex(x) = "2014-06-07"

これで変数xに06が格納されます。


まとめ

ここまでScalaで文字列を扱うための基本操作を紹介してきました。

Stringオブジェクトの生成方法やエスケープ文字は他の言語と似ていました。生文字リテラルでは、エスケープ文字を使わずに正規表現を記述したり、改行を含めて文字列を作ることが可能でした。文字列の結合、検索、抽出、置換も専用のメソッドが用意されていて、それぞれを組み合わせることで上手く文字列を抽出することが可能でした。

正規表現と生文字リテラルの組み合わせは非常に便利です。活用することをおすすめします!