やりたいこと
explode('_', '111_222');
とするだけで、111
と222
に分割してくれる便利なexplodeさん。
上記の'_'
の部分を、配列で渡したい、みたいな欲求が生まれた。
具体的には、
explode_ex(['_', '-'], '111_222-333');
とした場合に、戻り値がarray(3) {[0]=>'111',[1]=>'222',[2]=>'333'}
となってほしい。
※なぜこんなことを思い立ったのかが思い出せない。
作った関数
引数は基本的に、本家explodeさんに準拠。delimiterだけ配列OKにする。
/**
* explodeのdelimiterが配列でも大丈夫版
*
* @param array|string $delimiter 区切り文字列
* @param string $string 入力文字列
* @param int $limit
* @return array
*/
function explode_ex($delimiter, $string, $limit = PHP_INT_MAX) {
if (is_string($delimiter)) {
// 文字列型を渡されたら、普通にexplode
return explode($delimiter, $string, $limit);
} else if (!is_array($delimiter)) {
// stringでもarrayでも無ければ、処理せずに返却
return [$string];
}
$delete = 0;
if (intval($limit) === 0) {
// limitに0が入れられていた場合、1にしておく(explode準拠)
$limit = 1;
} else if (intval($limit) < 0) {
// マイナスの時は、最後の -limit 個の要素を除く全ての構成要素が返されます
$delete = -1 * $limit;
$limit = PHP_INT_MAX;
}
$list = []; // 分割した後の内容はここへ
// 上限数まで分割
for ($count = 0;$count < $limit;$count++) {
// 複数あるdelimiterのうち、最初に出てくる文字を探す
$min = strlen($string);
$target = '';
foreach ($delimiter as $search) {
$position = strpos($string, $search);
if ($position !== false && $min > $position) {
$min = $position;
$target = $search;
}
}
// 見つからない or 次で上限数に達してしまう場合
if ($target === '' || ($count + 1) === $limit) {
// 返却用配列にそのまま入れる
$list[] = $string;
// ループ終了
break;
}
// 最初に出てくる文字で2分割し、前半を返却配列へ、後半は更に分割
list($list[], $string) = explode($target, $string, 2);
}
// 末尾削除
if ($delete > 0) {
for ($i = 0;$i < $delete;$i++) {
array_pop($list);
}
}
return $list;
}
動作結果
var_dump(explode_ex(['/', '-', ':', ' '], '2019/07-20 00:20:30'));
// result ->array(6) { [0]=> string(4) "2019" [1]=> string(2) "07" [2]=> string(2) "20" [3]=> string(2) "00" [4]=> string(2) "20" [5]=> string(2) "30" }
var_dump(explode_ex(['/', '-', ':', ' '], '2019/07-20 00:20:30', 3));
// result ->array(3) { [0]=> string(4) "2019" [1]=> string(2) "07" [2]=> string(11) "20 00:20:30" }
var_dump(explode_ex(['/', '-', ':', ' '], '2019/07-20 00:20:30', -2));
// result ->array(4) { [0]=> string(4) "2019" [1]=> string(2) "07" [2]=> string(2) "20" [3]=> string(2) "00" }
var_dump(explode_ex(['あ','い','う'], 'qazかXSWあedcきVFRいtgbきNHYうujmくLKI'));
// result ->array(4) { [0]=> string(13) "qazかXSW" [1]=> string(13) "edcきVFR" [2]=> string(13) "tgbきNHY" [3]=> string(13) "ujmくLKI" }