« perl でリンクを抽出する | メイン | 二重起動の防止 »
2004年08月03日
CSV の行を分解
CSVをコンマで分けるのは一見簡単そうであるが、実は奥が深い。Perl では Text::CSV_XS モジュールを使うのが便利だ。たとえば、split 関数を使って「,」で分ければ、次のような単純な例はうまくいく。
$line='A,BB,CCC,,D'; @values=split(/,/,$line);しかし、これでは「,」や「"」を含む値を適切に扱うことはできない。値の中に「,」や「"」を含むときは値を「"」で囲み、含まれる「"」は「""」と記述するのだが、単純に「,」で切っては当然うまくいかない。
Perlメモ(http://www.din.or.jp/~ohzaki/perl.htm#CSV2Values)に詳しくやり方が書いてあった。難しくて解読困難だ。(^^;
$tmp=$line='"""北海道,札幌市""",ABC,"XX,XX","abc"'; $tmp=~s/(?:\x0D\x0A|[\x0D\x0A])?$/,/; @values=map {/^"(.*)"$/?scalar($_=$1,s/""/"/g,$_):$_} ($tmp =~ /("[^"]*(?:""[^"]*)*"|[^,]*),/g);
Text::CSV_XS を使って以下のようにすることもできる。日本語を扱わないなら {binary=>1} は不要である。
use Text::CSV_XS; $csv=Text::CSV_XS->new({binary=>1}); #create a object $line='"北海道,札幌市",ABC,"XX,XX","""abc"""'; $status=$csv->parse($line); #parse a string @values=$csv->fields(); #get the fields print join("\n",@values);Text::CSV_XS は Active Perl なら標準で含まれているからこれが便利だろう。
投稿者 augustus : 2004年08月03日 22:36
トラックバック
このエントリーのトラックバックURL:
http://www.augustus.to/cgi-bin/blog/mt-tb.cgi/66