RFC 4180対応版 CSVレコードの分解
Posted feedbacks - Perl
Text::CSV_XSでさくっと.
1 | perl -MText::CSV_XS -le '$csv = Text::CSV_XS->new({binary=>1}); $csv->parse("\"aaa\",\"b\nbb\",\"ccc\",zzz,\"y\"\"Y\"\"y\",xxx"); map { print ++$i, " => $_" } $csv->fields()'
|
昔書いたコードってホントよくわからないものですね(笑 サンプル出力するとうまく出るのでちゃんと機能しているはず^^;; "aaa","b bb","ccc","",zzz,"y""Y""y","xx,x",,, 1 => aaa 2 => b bb 3 => ccc 4 => 5 => zzz 6 => y"Y"y 7 => xx,x 8 => 9 => 10 =>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | sub splitCSV($@)
{
my $work = shift || ''; # CSV形式の1レコードの文字列
my $sepCHAR = shift || ','; # 区切り文字
my $quoteCHAR = shift || '"'; # 引用符
return 0 if( $work eq '' );
$work .= $sepCHAR; # レコードの最後に , を追加
# とりあえず列の取り出し;
my @result = ($work =~ m/((?:$quoteCHAR$quoteCHAR|$quoteCHAR.*?[^$quoteCHAR]$quoteCHAR)[ \t]*|(?:.*?))$sepCHAR/sg);
######################
# レコードのデータに
# 引用符 が含まれていた場合
# 引用符 を はずして 引用符二個で一つに変換する
if( $work =~ m/$quoteCHAR/ ){
my $count = 0;
foreach $work ( @result ){
#######################
# 取り出した列の整形
# ""のみはデータ無しで空白に置換
$work = '' if( !defined($work) || $work eq "$quoteCHAR$quoteCHAR" );
$work =~ s/$quoteCHAR(.+)$quoteCHAR/$1/s; # " で囲まれていた場合 "を取り外す
$work =~ s/$quoteCHAR$quoteCHAR/$quoteCHAR/g; # "" は " に変換
$result[ $count ++ ] = $work; # 変換後の結果で更新
}
}
return @result;
}
my @field;
my $record = <<CSV;
"aaa","b
bb","ccc","",zzz,"y""Y""y","xx,x",,,
CSV
print "$record\n";
@field = &splitCSV($record);
for( my $n=0; $n<=$#field; $n ++)
{
print "$n => $field[$n]\n";
}
|


raynstard
#3389()
Rating1/1=1.00
[ reply ]