ダブルクォート区切りに対応したカンマ区切りの文字列を分解する

「,」でくくられた文字列を配列に分解する。 ただし「"」でくくられている「,」では分解しない。

例:「"ねこ,猫",ねずみ,うし,とら,鵜」
・配列
ねこ,猫
ねずみ
うし
とら



「"」を文字列として認識させたい場合は「\"」とする。
例:「\"テスト\",test」
・配列
"テスト"
test


ソースコード
	$smps[]="ねこ,ねずみ,うし,とら,鵜";
	$smps[]='"ねこ,猫",ねずみ,うし,とら,鵜';
	$smps[]='ねこ,"ねずみ,n",",うし,",とら,鵜';
	$smps[]='"赤い,ネコ",ねずみ,うし\"大型\",とら,"黒い,鵜"';
	$smps[]='"ねこ,ねずみ,うし,とら,鵜';
	$smps[]=",,,2403249,73982,3.08%,,,";
	$smps[]=",,";
	$smps[]='\"one';
	$smps[]="";
	$smps[]=null;
	$smps[]='"",,\",",","",';

	$data=null;
	foreach($smps as $smp){
		$ary=splitEx($smp);

		$ent['str']=$smp;
		$ent['ary']=$ary;
		$data[]=$ent;
	}


	define("SDQ","%DXQ#");
	define("SSQ","%SXQ#");

	function splitEx($str){

		//「\"」を待避する。
		$s=$str;
		$n=mb_strpos($s,'\"',0);//「\"」を検索
		$sdqFlg=false;
		if(!empty($n) || $n===0){
			$sdqFlg=true;
			$s = str_replace('\"', SDQ, $s);//「\"」を待避させる。

		}

		//「"」でくくられた「,」を待避する。
		$dqFlg=false;
		$n=mb_strpos($s,'"',0);//「"」を検索
		if(!empty($n) || $n===0){
			$dqFlg=true;

			$ary=explode ( '"' , $s );
			for($i=1;$i$v){
				$ary[$i]=str_replace(SSQ,',', $v);
			}
		}


		return $ary;
	}




ねこ,ねずみ,うし,とら,鵜
ねこ
ねずみ
うし
とら


"ねこ,猫",ねずみ,うし,とら,鵜
ねこ,猫
ねずみ
うし
とら


ねこ,"ねずみ,n",",うし,",とら,鵜
ねこ
ねずみ,n
,うし,
とら


"赤い,ネコ",ねずみ,うし\"大型\",とら,"黒い,鵜"
赤い,ネコ
ねずみ
うし"大型"
とら
黒い,鵜


"ねこ,ねずみ,うし,とら,鵜
ねこ,ねずみ,うし,とら,鵜


,,,2403249,73982,3.08%,,,
2403249
73982
3.08%


,,


\"one
"one








"",,\",",","",
"
,