[AD] Scalaアプリケーションの開発・保守は合同会社ミルクソフトにお任せください
Scalaの文字列で置換を行う方法をご紹介します。
文字列で指定する
マッチした部分すべてを置換する
最も単純な置換は、以下のようにString
クラスのreplace
メソッドを用いて、置換対象と置換先の文字列を指定することで行います。
val str = "hello abc" println(str.replace("abc", "world"))
結果は以下のように出力されます。
hello world
replace
メソッドはマッチした文字列すべてを置換します。
val str = "foofoofoobar" println(str.replace("foo", "bar"))
以下のようにすべて置換されて出力されます。
barbarbarbar
最初にマッチした部分のみを置換する
最初にマッチした部分のみを置換したい場合、replaceFirst
メソッドを使うことで解決することができます。
val str = "foofoofoobar" println(str.replaceFirst("foo", "bar"))
以下のように先頭のみ置換されて出力されます。
barfoofoobar
先頭一文字のみ置換する
文字列の先頭一文字を置き換えたい場合、tail
メソッドを使うと解決できます。
tail
メソッドは文字列の先頭から一文字取り除いたものを返します。
val str = "fello world" println("h" + str.tail)
以下のように出力されます。
hello world
末尾一文字のみ置換する
また、末尾一文字を置き換えたい場合は、init
メソッドを使うことで解決できます。
init
メソッドはtail
メソッドとは反対に末尾一文字を取り除いたものを返します。
val str = "hello worlo" println(str.init + "d")
以下のように出力されます。
hello world
位置を指定して一文字のみ置換する
位置を指定して一文字だけを置換したい場合は、updated
メソッドを使うと解決できます。
println("helio world".updated(3, 'l'))
以下のように出力されます。
hello world
正規表現を使う
文字列を正規表現として扱う
正規表現によるマッチで置換を行いたい場合、replaceAll
メソッドを使うことで解決することができます。
例えば、以下のようにアルファベットの部分を置き換えたい場合。
val str = "00000agkkjpaviwadsd00000" println(str.replaceAll("[A-z]+", "foo"))
以下のように出力されます。
00000foo00000
replaceAll
メソッドはreplace
メソッドと違い、第一引数を正規表現と解釈して置換を行います。
Regexオブジェクトによる置換
これまではJavaのString
のメソッドによる置換を紹介してきました。
ここからはScalaのRegex
クラスを使った置換を紹介していきます。
Regex
クラスでは置換を始め、正規表現を使ったメソッドを多く提供しています。
String
クラスのr
メソッドを使うことでRegex
オブジェクトを作ることができます。
マッチした最初の部分を置換する
replaceFirstIn
メソッドではマッチした最初の部分を置換してくれます。
val re = "[A-z]+".r // Regexオブジェクトに変換 println(re.replaceFirstIn("aaaa111bbb1222ccc", "000"))
以下のように出力されます。
000111bbb1222ccc
マッチしたすべての部分を置換する
マッチしたすべての部分を置換するにはreplaceAllIn
メソッドを使います。
val re = "[A-z]+".r println(re.replaceAllIn("aaaa111bbb1222ccc", "000"))
以下のように出力されます。
0001110001222000
マッチした部分すべてに関数を適用して置換する
replaceAllIn
メソッドは第二引数にMatch
オブジェクトを引数にとる関数を受け取ります。
以下はマッチした文字列を1文字だけ切り取り置換する例です。
val re = "[A-z]+".r println(re.replaceAllIn("aaaa111bbb1222ccc", m => m.group(0).substring(0, 1)))
m
はMatch
オブジェクトで、group(0)
でマッチした部分をString
で取得しています。
最後にsubstring
メソッドで0文字目から1文字を切り出して置換させています。
以下のように出力されます。
a111b1222c
コレクションを使って置換する
List
やSeq
といったコレクションで置換したい文字列を複数指定したい場合、mkString
メソッドを使うことで解決できます。
引数を1つ取るmkString
メソッドは、セパレータとなる文字列を指定してあげることで、その文字を使ってリストの要素を連結してくれます。
println(List("foo", "bar").mkString("|").r.replaceAllIn("foobarbaz", "X"))
|
で連結することでList
のすべての要素にマッチするよう正規表現を組み立てています。
以下のように出力されます。
XXbaz
Seq
の場合も同様に行えます。
println(Seq("foo", "bar").mkString("|").r.replaceAllIn("foobarbaz", "X"))
結果も同じく以下の通りです。
XXbaz
特殊文字を置換する
エスケープを使うことで、特殊文字も置換させることができます。
例えば、以下は.
を置換する例です。
.
は通常任意の一文字を意味しますが、\\.
とすることで、ただの.
として解釈させることができます。
val re = "\\.".r println(re.replaceAllIn(raw"hello.world", " "))
以下のように出力されます。
hello world
"
の場合、"\""
とすることでエスケープが可能です。
以下は"Hello World"
な文字列から"
を取り除く例です。
Scalaでは"
を3つにすることで特殊文字をエスケープすることができます。
val re = "\"".r println(re.replaceAllIn(""""hello world"""", ""))
以下のように出力されます。
hello world
StringBuilderを使う
不変なString
クラスは置換を行うたびに新しいオブジェクトを生成するため、メモリの消費が大きくなります。
そこで、可変なStringBuilder
クラスのreplace
メソッドの紹介をします。
第一引数に置換開始地点、第二引数に終了地点を指定し、第三に置換後の文字列を指定します。
そのため、予め置換を行う範囲を知っておく必要があります。
範囲を指定し、abc
をworld
に置換する例です。
val sb = new StringBuilder("hello abc") println(sb.replace(6, 9, "world").toString())
以下のように出力されます。
hello world