2019年10月29日

String.split() の第二引数の挙動

文字列操作の関数 split に返り値の長さを調節する引数(たいてい二番目)を渡した場合、結果は言語によって違う。

Python

str.split(sep=None, maxsplit=-1)
文字列を sep をデリミタ文字列として区切った単語のリストを返します。maxsplit が与えられていれば、最大で maxsplit 回分割されます (つまり、リストは最大 maxsplit+1 要素になります)。

str.split — Python 3.8.0 ドキュメント

>>> "1-2-3-4-5".split(",", 3);
['1', '2', '3', '4-5']

分割する回数を指定する。余分は最後尾にまとめられる。

Ruby

split(sep = $;, limit = 0) -> [String]
第 1 引数 sep で指定されたセパレータによって文字列を limit 個まで分割し…

String#split (Ruby 2.6.0)

> "1-2-3-4-5".split(",", 3);
=> ["1", "2", "3-4-5"]

返り値の配列の長さを指定する。N-1回分割した余分がまとめられるのは Python と同じ。

JavaScript

str.split([separator[, limit]])
引数 limit (Optional)
見つかった分割結果の数の制限を指定する整数です。split() メソッドは、分割した項目数が limit に一致する(…)まで、すべての separator のマッチを分割します。

String.prototype.split() - JavaScript | MDN

> "1-2-3-4-5".split(",", 3);
[ '1', '2', '3' ]

長さを指定するのは Ruby と同じだが、余分な文字列は捨てられる。なんなのこの挙動。

余りの部分が欲しい場合は第二引数を渡さずに、返ってきた配列の前半分を別変数に格納しつつ、配列の残りを分割に使った文字列でまた連結して追加する。

var sep = ",",
    arr = "1-2-3-4-5".split(sep),
    result = arr.splice(0, 2);
result.push(arr.join(sep)); 
// [ '1', '2', '3-4-5' ]

PHP

歴史的な理由により、文字列の分割と配列の連結は闇が深い。

  • split という関数はあったが廃止されてしまった
  • 一見それらしい str_split はN文字ずつにバラす固定長分割
  • 正しい代替は explode (通常の文字列で分割) または preg_split (正規表現で分割)。PHP には正規表現クラス・リテラルがないので関数単位で分かれている
  • ちなみに連結関数 implode は引数の順番がてれこでも受け付ける。join という、馴染みやすいが split 亡き今はうまみが少ないエイリアスもある

explode ( string $delimiter , string $string [, int $limit = PHP_INT_MAX ] ) : array
limit に正の値が指定された場合、返される配列には 最大 limit の要素が含まれ、その最後の要素には string の残りの部分が全て含まれます。

PHP: explode - Manual

これも配列の要素数を指定するタイプ。ただし Ruby 気分で書いてると引数の順番で混乱する。

<?php print_r(explode(",", "1-2-3-4-5", 3)); ?>
⇒ Array ( [0] => 1 [1] => 2 [2] => 3-4-5 )

その他

ついでなので他の言語も調べてみた。

そんな関数はないよ派

  • C、C++
  • Haskell
  • Common Lisp、Scheme

そんなオプションないよ派

長さ指定派

回数指定派

  • Python
posted by かぷらす at 22:49| Comment(0) | 調査 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
コチラをクリックしてください