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 なら標準で含まれているからこれが便利だろう。
Posted by augustus at 2004年08月03日 22:36
| TrackBack