- ベストアンサー
CSVファイルをperlプログラムで処理する場合
すみません、度々perl初心者のものです。 CSVファイルを1行ずつ読み込んで処理をしたい場合、 1項目内のデータの中に改行がある場合、 どのような方法で対処出来るでしょうか? 例えば "aaa,bbb,ccc ddd,eee,fff" 上記のようにcccとdddの間に改行が入ってるため 本当は1レコードのはずなのに2レコードとして 処理を行ってしまう。 perlで何かやり方はあるのでしょうか? csvを加工するのもよいのですが、データが多量に あるため、プログラム上でなんとかしたいと思うのですが。。。 すみません、宜しくお願い致します。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
自分でしたら、まず、ダブルクォテーションで囲まれている改行コードを、すべて何かの文字に置換してしまいます。その後は、普通のCSVと同様に処理をして、最後に置換した文字を改行コードに戻してやります。 my $file = 'data.csv'; open IN, '<', $file or die "cannot open $file : $!"; $/ = ""; my $data = <IN>; close IN; while($data =~ s/\"(.+)\n(.+)\"/$1<>$2/g){ } # 後は普通のCSVとして処理(例) foreach(split /\n/, $data){ my @data = split /,/; map{ s/<>/\n/g } @data; print "@data\n"; }
その他の回答 (4)
- Tacosan
- ベストアンサー率23% (3656/15482)
$/ を undef にして全部読み込んでから /"(.*?)"/m するとか?
- rafysta
- ベストアンサー率45% (24/53)
# No.3の訂正 while($data =~ s/\"(.+)\n(.+)\"/$1<>$2/g){ } じゃなくて while($data =~ s/\"(.+)\n(.+)\"/"$1<>$2"/g){ }
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
安易な方法で、必要なパターンを満たしているか自信がないですが、こんな感じでどうでしょう。 ---------------------------------------------------------------- use encoding "Shift_JIS"; sub readCSVline($){ my $FH = shift ; my $line = ""; my $count=0; while(<$FH>){ $count += tr/\"/\"/;#" の数を数える $line .= $_; #条件が成立するまで、行を拡張する if($count % 2 == 0){ #偶数倍になっていたらマッチングしているとして読み込んだ行を返す return $line; } } } open(IN, "<data.csv"); while($line = readCSVline(IN)){ #一行の処理 } close(IN);
- galluda
- ベストアンサー率35% (440/1242)
がると申します。 ちと面倒な処理にはなるのですが。状態遷移プログラムが書けるのであれば(Perlで十分に記述は可能です)、処理は出来るかと。…いやまぁ状態遷移じゃなくても書けるのですが、状態遷移のほうが楽なので、程度なのですが。 googleあたりで「CSV 状態遷移」とかで調べたりすると色々と情報など出てくるかと思います。