色々な言語の文字列分割個数指定
「文字列を特定の区切り文字で分割し、配列相当のデータ構造で返す」という関数/メソッドは多くの言語が組込みで提供している。そして、その関数/メソッドの引数には区切り文字に加えて、オプションとして分割する個数を与えることができる。
この分割個数の指定の仕様が、言語によって微妙に異なっていたのでまとめてみた。
以下、全て"1:2:3:4:5"
という文字列をコロンで分割する場合で考える。
Python の場合(str.split
)
第2引数を「分割処理を行う上限回数」として扱う。上限を超えた分は分割せず、最後の要素に残る。
print("1:2:3:4:5".split(":", 3))
上記コードだと3
と4
の間までを分割し、それ以降は分割しない。
$ python3 -V $ python3 split.py ['1', '2', '3', '4:5']
JavaScript の場合(String.prototype.split
)
第2引数を「分割後の最大個数」として扱う。上限を超えた分は捨てられる。
console.log("1:2:3:4:5".split(":", 3))
上記コードだと2
と3
の間まで分割し、3
の後ろのコロン以降は捨てられる。
$ node -v v8.4.0 $ node split.js [ '1', '2', '3' ]
Ruby の場合(String#split
)
第2引数を「分割後の最大個数」として扱う。上限を超えた分は分割せず、最後の要素に残る。
p "1:2:3:4:5".split(":", 3)
上記コードだと2
と3
の間まで分割し、それ以降は分割しない。
$ ruby -v ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin16] $ ruby split.rb ["1", "2", "3:4:5"]
Java の場合(String.split
)
Ruby と同様。
import java.util.Arrays; class Split { public static void main(String[] args) { System.out.println(Arrays.toString("1:2:3:4:5".split(":", 3))); } }
$ java -version java version "1.8.0_144" Java(TM) SE Runtime Environment (build 1.8.0_144-b01) Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode) $ java Split [1, 2, 3:4]
Go の場合(strings.SplitN
)
package main import ( "fmt" "strings" ) func main() { fmt.Printf("%q\n", strings.SplitN("1:2:3:4:5", ":", 3)) }
$ go version go version go1.9 darwin/amd64 $ go run split.go ["1" "2" "3:4:5"]
PHP の場合(explode
)
Ruby, Java, Go と同様。(メソッドでなく関数)
Go のstrings.SplitN
とは微妙に引数の取り方が異なる。紛らわしい。
<?php print_r(explode(":", "1:2:3:4:5", 3));
$ php -v PHP 7.1.8 (cli) (built: Aug 7 2017 15:02:45) ( NTS ) Copyright (c) 1997-2017 The PHP Group Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies $ php split.php Array ( [0] => 1 [1] => 2 [2] => 3:4:5 )
なお同じことをしそうな組み込み関数str_split
は全く仕様が異なる。紛らわしい。
まとめ
Python, JavaScript, Ruby で仕様が違うことに気づいたのでいざ色々と調べてみたら Python と JavaScript 以外はほぼ同じだった。
Python, JavaScript の分割仕様もだが、PHP もいざ使う時に嵌りそうなので注意したいところ……