こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

カンマ区切りのCSVについて

ブログの引越しの依頼を受け、元データ(CSV)をもとに
出力ページを作成しているのですが、

003,あああ,一昨日は晴れていました。,そうでしたね,2009/06/03
002,bbbbbb,昨日は晴れです。,そうですか,2009/06/02
001,aaaaaa,今日は晴れです。,そうですね,2009/06/01
   ・
   ・
   ・
という内容のカンマ区切りのhoge.csvがあります。
(id,title,text,coment,day)

これを
$array=file(hoge.csv);
for($i=0;$i<count($array);$i++){
$data=expolde(",",$array[$i]);
ehco $data[2];
}
としてカンマで分割し、それぞれのデータを整形したいのですが、
所々text部分($data[2])の内容が

「今日は,晴れです。<br />とても,気持ちが良いです。」

など「,」を使用していて、当然ですが

  $data[2]を出力したら⇒「今日は」
  $data[3]を出力したら⇒「晴れです。<br />とても」

となってしまいます。

 ●元のCSVはいじれない。(データ量が多いため編集不可能)
 ●前後($data[1]=title/$data[3]=coment)も決まった形ではない。(正規表現で抜き出せない)
 ●SQLは使えない。

こういう場合どのような解決策があるでしょうか?

投稿日時 - 2009-06-03 09:33:27

QNo.5012895

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

4人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

結局のところ、正確な数値としてはどれぐらいでしょうか?
・CSV全体の行数
・カンマが多い行の行数

また、そのCSVを最終的に別のブログにインポートするということでしょうか?

これを前提として、カンマの多い行がどうにかがんばって編集できるのであれば、
不正な行のみ、title,text,commentのフィールドををtextフィールドに集約して、
タイトルを例えば「■■エラー■■」などのように目立つタイトルをくっつけて
アップして、こつこつ手動で再編集をかけて行く、しかないかなぁと思います。

あとは、「●SQLは使えない」とのことですが、もしSQLを使って何らかの操作を
ご発想でしたら、
http://sourceforge.jp/projects/posql/
こちらの「Posql」を使うと、ファイルベースのDBでSQL操作が行えます。

投稿日時 - 2009-06-03 20:36:23

ANo.4

No.3です。
出力されたCSVで「,」を含む1フィールドが規格通りに「"」で囲まれているのなら、fgetcsv()関数を使うと良いですよ。
フィールド区切りのカンマと文字列中のカンマを自動的に区別してくれますので。

投稿日時 - 2009-06-03 13:37:10

お礼

たびたびありがとうございます。

>出力されたCSVで「,」を含む1フィールドが規格通りに「"」で囲まれているのなら
残念ながら・・。

投稿日時 - 2009-06-03 14:58:00

ANo.3

カンマが誤混入しているフィールドが$data[2]の1つだけなら、という前提ですがこんな手が使えると思います。
1行分を配列に読み込んだら、配列の数count($data)を調べます。
本来のフィールド数より多かったら、$data[2]と$data[3](必要に応じて$data[n]まで)を連結します。

連結したら、後々のことを考えて$data[2]のカンマを「、」に置換しておくといいかもしれませんね。

投稿日時 - 2009-06-03 12:02:49

お礼

ありがとうございます。

>カンマが誤混入しているフィールドが$data[2]の1つだけなら、という前提ですが
残念なことに・・$data[3]もやられてました。

しかし、配列の数で分けるというアイディアは応用できそうです!
この方法なら、$data[2]+$data[3]を抜き出すことが出来ますね。
あとは・・どうやって連結した2つを切り離すか・・。

$data[2]+$data[3]を","で分割して・・。う~・・ん。
せめて$data[2]か$data[3]になにか特徴があれば良いのですが・・。

投稿日時 - 2009-06-03 14:54:14

ANo.2

基本的には「対策はない」と思います。

> 今日は,晴れです。<br />とても,気持ちが良いです。
CSVフォーマットにおいては、以下のように書くのが正しいので。(改行も本来は \n ですね)

× 今日は,晴れです。<br />とても,気持ちが良いです。
○ "今日は,晴れです。<br />とても,気持ちが良いです。"

データの区切りが不完全な形で出力されています。
CSV出力するプログラムの方に問題があるわけで、不完全なCSVデータの区切り文字を確実に判別する手段はありません。
CSV出力するプログラムで正しいCSVを出力してもらうように修正してもらう方法が確実です。
# 改行をエスケープしているにも関わらず、カンマをエスケープしなかったのは片手落ちですね…。
# 現フォーマットに沿って修正するなら「カンマを数値参照に置換する」のがいいかな、と思います。

** 不確実でも良ければ **
「カンマを含むデータが一つだけ」とわかっているならば、正規表現で抽出することは出来ます。
例えば、以下のようにフォーマット定義するならば

* フォーマット定義
id … 数字のみ
title … 改行、カンマ以外
text … 改行、カンマ含む
coment … 改行、カンマ以外
day … yyyy/mm/dd

* 正規表現
^(\d+),([^,]*),(.*),([^,]*),(\d{4},\d{2}/\d{2})$

このように1行全てをマッチさせることで各々のデータを参照できます。
ただし、この方法では「カンマを含められるのは1データだけ」です。
title, text, coment 全てでカンマを含む可能性がある場合は、データの区切りを判別できないので抽出できません。

> ●前後($data[1]=title/$data[3]=coment)も決まった形ではない。(正規表現で抜き出せない)
ひょっとしてデータの順番にも変動があるのでしょうか…?

id,title,text,coment,day

だったり、

coment,id,day,title,text

だったりする、という意味ですか?
その場合はデータの並び順を判定する基準がないと思いますが、現在はどうやってデータを抽出しているのでしょうか。
そもそもそれはCSVと呼べるのかどうか…。

どちらにせよ、確実性を求めるならCSV出力側を修正するよう求める必要があると思います。

投稿日時 - 2009-06-03 11:56:51

お礼

ありがとうございます。

>○"今日は,晴れです。<br />とても,気持ちが良いです。"
残念ながら「"」では囲っていませんでした。

>改行をエスケープしているにも関わらず、カンマをエスケープしなかったのは片手落ちですね…。
元のサイトではどのようにして書き出していたのか・・。なぜ、CSVがこのような形なのか私も謎です。

>** 不確実でも良ければ **
正規表現の定義、ありがとうございます!
ですが・・。最悪です。確認したところ「coment」部分にも「,」を使っていました。・・なんという・・。

>ひょっとしてデータの順番にも変動があるのでしょうか…?
説明不足ですいません。順番自体は変動しないです。
ただ、前後のtitle,comentともに空だったり、英数字だったり、タグが入っていたりで、まったくつかみ所が無いという意味で「決まった形ではない。」と書きました。

>どちらにせよ、確実性を求めるならCSV出力側を修正するよう求める必要があると思います。
全くそのとおりです。もうCSVは見たくないというのが本音です。

投稿日時 - 2009-06-03 14:22:36

ANo.1

人間が見ても判断できないレベルですので、残念ながら分離は不可能かと思います。

title=今日は,日曜日。
body=いい天気ですね。



title=今日は
body=日曜日。いい天気ですね。

かもしれないですし。

投稿日時 - 2009-06-03 11:51:50

お礼

ありがとうございます。
おっしゃる通りです。
なにかしらの法則があれば万事解決できそうなんですが、
どこで区切ればいいのやら・・。

投稿日時 - 2009-06-03 13:40:11

あなたにオススメの質問