• ベストアンサー

perlでcsvファイルを読む(ダブルコーテーション内カンマを無視したい)

perlでCSVファイルを読み込むスクリプトを作っています。 以下のようなCSVファイルがあります。 ■CSVファイル 東京,よろしくお願いします。 大阪,はじめまして 九州,"5,000円でお願いします" カンマで区切り、以下のようにすると、"5,000円"の部分が2つに分かれてしまいます。 ($data1,$data2) = split(/,/,$all_data) 前後にダブルコーテーションがあった場合、中のカンマで区切らないような良い方法はないでしょうか? 環境: Perl 5.8.5

質問者が選んだベストアンサー

  • ベストアンサー
  • Ceren
  • ベストアンサー率49% (90/183)
回答No.3

Text::ParseWords を使ってこんなのはどうですか。(例ではparse_lineを使っています) もしquoteを残したければundefを1に変えてください。 use Text::ParseWords; $" = "\t"; while (<DATA>) { chomp; my @words = &parse_line(',', undef, $_); print "@words\n"; } exit 0; __DATA__ 東京,よろしくお願いします。 大阪,はじめまして 九州,"5,000円でお願いします"

tomkeifer
質問者

お礼

ありがとうございます。 この方法でできました。 ダブルコーテーション内のカンマで分割されることなく期待どおりの動作です。 助かりました。

その他の回答 (3)

  • zxcv0000
  • ベストアンサー率56% (111/196)
回答No.4

CSV は、プログラミングの勉強ネタの宝庫だと思います。 " " で囲まれたセルは、「,」(カンマ) 以外でも以下の注意が必要です。 勉強のために取り組んでみるのは良い事ですが、手っ取り早く実用に耐える物が欲しい場合は自分に合った仕様のモジュールを探す選択肢もありかと思います。 1 " が閉じない内に改行が来たら、それはテーブルとしての改行では無くセルに埋め込まれた改行文字。 あるバージョンの MSExcelは、テーブルとしての改行は CRLF、 セル内埋め込みは LF と使い分けるかも知れませんが、それを期待してはいけません。 (業界規格では、CSV中の改行は全て CRLF と規定されていたと思います) 2 " " で囲まれた中に "" (2個連続した")が現れたら、それはセルに埋め込まれた 1個の " です。 3 MS-Excel が 「1/2」を「1月2日」に変換するのを抑止する方法は、MS-Excel のバージョンにより違います。 例えば Excel2003 向には ="1/2" とか"=""1/2""" と書いたりします。 読み込むCSVの作成ソフトによってはそういう工夫が入っているかも知れません。 4 その他、MS-Excel が日付や数値と解釈するのが不都合なケースは結構あって、手作業やアプリケーションで作成されたCSVはそれらを文字列と認識させる為の工夫が入っているかも知れません。

tomkeifer
質問者

お礼

ご親切にありがとうございます。 今回は、データの吐き出し元がJavaですので、大丈夫だと思います。 他の回答で紹介されたparse_lineを使用することにします。 今後の参考なります。ありがとうございました。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

もうちょっとつめる必要があるけど #!/usr/bin/perl # -*- coding: utf8 -* use strict; use warnings; use feature ':5.10'; while (my $line = <DATA>) { chomp $line; my @fields; @fields = ($line =~ /([^",]* | "[^"]*") (?:,|$)/gx); say join ' : ', @fields; } __END__ abc,大阪,はじめまして,xxx def,九州,"5,000円でお願いします",yyy 結果: abc : 大阪 : はじめまして : xxx : def : 九州 : "5,000円でお願いします" : yyy : Text::CSV って今でもマルチバイト文字が入るとき面倒があるんだっけか?

tomkeifer
質問者

お礼

今回は、別の回答にあるparse_lineを使用することにします。 時間のあるときにお教えいただいた方法も勉強してみます。 回答、ありがとうございました。

  • lesstia
  • ベストアンサー率45% (44/96)
回答No.1

いろいろ方法はあるようですが、とりあえず ダブルクォート内のカンマを正規表現でマッチさせて一時的に置換して分割するのがいいらしいですね。

参考URL:
http://home.kanto-gakuin.ac.jp/~ahero/perl/anyway/csv/csv2.shtml
tomkeifer
質問者

補足

ありがとうございます。 なるほど。数字に挟まれたカンマを一時的に置き換えておくのですね。 せっかく回答いただいたのにすみません、 今回はデータがフリーコメントなので、前後が必ず数字であるというわけではないです。

関連するQ&A