(以下は、今日現在の話なので、将来は状況が変化していると思われます)
PHPのversion 5.2.1を使って、ちょっとしたプログラムを書いていたとき、文字列をCSVとみなして、カンマ(,)区切りで分割する処理が必要になりました。
とりあえず!ってことで、はじめのうちは、preg_split('/,/',・・・)で分割していたのですが、やっぱりどうしても、カンマを含むフィールドがでてきて、「a,b,"cde,fg",e」のような、ダブルクォートなどを使った、カンマのエスケープ処理が必要になってきました。
というわけで、PHPのマニュアルを見ると、
fgetcsv ファイルポインタから行を取得し、CSVフィールドを処理する
という、CSVファイルから読み出すときに分割してくれる関数はあるのですが、文字列に対して処理する関数は見当たりません。
ひょっとして、文字列をfopenするような関数もあるかな?と思ったけど、それも見当たりません。
まじかよ~なんだよ~・・・ってことで、FreeBSD使いなので、当然ports使いでもあるわけなので、いきなり「cd /usr/ports/lang/php5; make patch」 とかやって、PHP-5.2.1のソースコードを展開し、grep -Rとかで探しちゃうわけです。これだからFreeBSDはやめられません(笑)。
で、ソースコードをさらっと眺めてみたのですが、やっぱり、fgetcsvの処理の途中、フィールドに分ける処理が組み込まれちゃっているようで、文字列をCSVとして分割する関数は、見当たらないようです。
☆
ところが、ちょこっとgoogleで検索してみたりすると
str_getcsv CSV 文字列をパースして配列に格納する
なんて関数がでてくるじゃありませんか。
でも、php-5.2.1じゃ使えませんでした。なんだよ、このマニュアルは~。期待もたせやがってっ! ぷんぷん。
「might be only in CVS」とか書いてあるので、リリース前のバージョンのphpでのみ使えるってことでしょうか。
☆ ☆ ☆
で、結局どうやったかというと、
「,」を含むフィールドは、「,」を「;」に置換しておく
という、非常にその場しのぎな対策をして、お茶を濁すことにしました。
php-5.2.2とかになったら、str_getcsvが使えるようになっているだろう
きっと、そうに違いない!!
という望みをもって。
☆
なんか、ここに、それっぽいコードが書いてありますけどね・・・
http://www.php.net/manual/en/function.split.php
正規表現で次のようにして
返信削除preg_match_all('/"([^"]*)"(?=[\s,]+)[\s,]+/', $buf, $col);
$matches[1][n] のように参照すればCSVをテキストから読めると思います。ちなみ「"」からカンマの直前の「"」で囲まれた文字列にマッチします。ただ、間に「"」を含んではいけませんがそれは当たり前だと思うので例外処理をしませんでしたがバグの原因になるかも。「"」で囲まれていなければマッチしない仕様ですが、「|」をつかって分岐してやれば対応してやれないこともないかと。もちろん、間にいくつカンマがあっても問題ないです。
preg_match_all の第3引数が$colになっていますが、$matches の間違いでした。すみません。
返信削除どうもありがとうございます。解読してみます。
返信削除"~"の中で、"を「\"」でエスケープしたいとか、だんだんと欲が出てきてしまいそうなので、KISSの法則(よけいな機能を作りこまずに、単純にしておけ)で逃げるかもしれません・・・。