プロが教える店舗&オフィスのセキュリティ対策術

すみません、度々perl初心者のものです。
CSVファイルを1行ずつ読み込んで処理をしたい場合、
1項目内のデータの中に改行がある場合、
どのような方法で対処出来るでしょうか?

例えば

"aaa,bbb,ccc
ddd,eee,fff"

上記のようにcccとdddの間に改行が入ってるため
本当は1レコードのはずなのに2レコードとして
処理を行ってしまう。
perlで何かやり方はあるのでしょうか?
csvを加工するのもよいのですが、データが多量に
あるため、プログラム上でなんとかしたいと思うのですが。。。

すみません、宜しくお願い致します。

A 回答 (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";
}
    • good
    • 0

$/ を undef にして全部読み込んでから /"(.*?)"/m するとか?

    • good
    • 0

# No.3の訂正


while($data =~ s/\"(.+)\n(.+)\"/$1<>$2/g){
}
じゃなくて
while($data =~ s/\"(.+)\n(.+)\"/"$1<>$2"/g){
}
    • good
    • 0

安易な方法で、必要なパターンを満たしているか自信がないですが、こんな感じでどうでしょう。


----------------------------------------------------------------
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);
    • good
    • 0

がると申します。


ちと面倒な処理にはなるのですが。状態遷移プログラムが書けるのであれば(Perlで十分に記述は可能です)、処理は出来るかと。…いやまぁ状態遷移じゃなくても書けるのですが、状態遷移のほうが楽なので、程度なのですが。

googleあたりで「CSV 状態遷移」とかで調べたりすると色々と情報など出てくるかと思います。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!