覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

Kotlin - 文字列の分割

Java で 文字列分割する時は、 String クラスの split メソッドを利用することになります。
分割した文字列を配列にして返してくれます。

例えば、"100-123-A500-10" という文字列があったとして、"-" で区切りたいと思った時は以下のようになります

String str = "100-123-A500-10";
String[] array = str.split("-");

System.out.println(java.util.Arrays.toString(array));

実行結果は以下の通りです。予定通り "-"(ハイフン)で区切られている事が分かります。

[100, 123, A500, 10]


次に、 "100.123.A-500.10" という文字列があったとして、"." で区切りたいと思った時に以下のようなコードを書いたとします。

String str = "100.123.A-500.10";
String[] array = str.split(".");

System.out.println(java.util.Arrays.toString(array));

この場合の実行結果は以下の通りで、空の配列です。なんだか予定したものとは感覚的にずれます。

[]

正直、Java経験者ならこれはほとんどの人が一度は通る道なような気がします。
String#split メソッドは、引数として正規表現をとります。
"."(ドット)を引数に指定してしまうと、任意の文字を表現する正規表現 となってしまい、こんな結果になります。

例えば以下のように書く事で、 望む結果を得ることができます。

String str = "100.123.A-500.10";
String[] array = str.split("\\.");

System.out.println(java.util.Arrays.toString(array));

実行結果は以下の通りです。

[100, 123, A-500, 10]


Kotlinの場合

Kotlinでは、上記のような紛らわしいメソッドを隠蔽して、異なる引数を持つ split という名前のオーバーロードされた拡張関数で置き換わっています。

split に対して正規表現を渡すためには、String ではなく Regax 型の値が必要になります。
これによって、メソッドに渡される値が、プレーンテキストとして解釈されるのか、正規表現として解釈されるのかが明確になります。

正規表現として渡す場合のコードは以下のようになります。文字列を toRegax 関数で正規表現に変換しています。

val str = "100.123.A-500.10"
val array = str.split("\\.".toRegex())  // 正規表現として渡している事が明確

println(array)

実行結果は以下の通りです

[100, 123, A-500, 10]


"."(ドット) だけではなく "-"(ハイフン)でも分解したい場合は以下のようになります

val str = "100.123.A-500.10"
val array = str.split("\\.|-".toRegex())  // 正規表現として渡している事が明確

println(array)

実行結果は以下の通りです

[100, 123, A, 500, 10]


toRegax関数を使わずに、そのまま "." (ドット)を渡すとプレーンテキストとして扱われ、その文字列がデリミタとなります。

val str = "100.123.A-500.10"
val array = str.split(".")  // プレーンテキストのデリミタとして扱われる

println(array)

実行結果は以下の通りです

[100, 123, A-500, 10]


プレーンテキストを引数に渡すパターンで、 "."(ドット) だけではなく "-"(ハイフン)でも分解したい場合は以下のように書けます

val str = "100.123.A-500.10"
val array = str.split(".", "-")  // プレーンテキストのデリミタとして扱われる

println(array)

実行結果は以下の通りです

[100, 123, A, 500, 10]


まとめ

文字列の分割という基礎的な処理に対しても、Javaに比べて直感的で分かりやすい操作(関数)が提供されていることが分かりました。