カンマ入りの文字列をCSVで扱いたい

同じ問題意識の情報は(当然のことながら)検索で見つかりました。

カンマ入りデータをCSVで出力するには

ダブルクオーテーションで囲う形式を割りと見るけれど、
そういう意味だったんだねぇ。(数字以外は囲む⇒エクセルではカンマのみ囲う)

これで解決。

(ついでに、行きがけの駄賃で面白い情報を拾ったが、本件とは無関係。CSV形式で保存した際カンマの数が17行以降異なる


‥と思ったが、そうではなかった。
ダブルクォーテーションではさむ場合、今度は、ダブルクォーテーション自身が入っていた場合の挙動を知らなければならない。


ダブルクォーテーションのエスケープは、ダブルクォーテーション自身らしい。
http://q.hatena.ne.jp/1292299330

つまり、2個のダブルクォーテーションを1個とエクセルはみなすようだ。

なら、3個のダブルクォーテーションがあった場合、どのペアを1個とみなすんだろうか?

いろいろ試した結果、次のような挙動が分かった。

  • 2個のダブルクォーテーションは、まず1個とみなして、これは囲うダブルクォーテーションにはカウントされない。
  • ペアからあぶれたダブルクォーテーションは、まず、囲いの終端として消費された場合はそこで消える。
  • 囲いが終わった後は、ペアのダブルクォーテーションは1個とみなすが、ペアからあぶれたもの、単独のダブルクォーテーションは、1個のダブルクォーテーションとして表示される。

だとすれば、

  1. まず、カンマを含む文字列のダブルクォーテーションを全て引き続いた2個にする("⇒"")
  2. その文字列を、ダブルクォーテーションで囲う

で対処可能のように思える。

例)慣れない正規表現でおっかなびっくり作ったもの
function commaEscape4csv($str)
{
  if(!(strstr($str, ',') === False)){
    $str = preg_replace('/"/', '""',$str);
    $str = '"' . $str . '"';
  }
  return $str;
}