- PR -

csvデータを正規表現で抽出する

投稿者投稿内容
hihi
常連さん
会議室デビュー日: 2002/08/30
投稿数: 29
お住まい・勤務地: 名古屋
投稿日時: 2004-08-19 16:19
"aa","s\"f","ss,12"文字列を[aa] [s"f] [ss,12]に個々のデータを抽出したい。
その文字列の正規表現の書き方を誰が教えてくれませんか?
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2004-08-19 16:39
たぶん、短いのは作れない。
”と , の解釈が 後方の文字列全体に依存するから。
(短距離パターンを見るだけで解決しないから)

ごまかしレベルなら
","
でスプリット。手作業エディタ処理なら使える
=============================================
文字列内の引用符を ダブらせるのは
汎用機の アセンブラやCOBOL 以来のものです。
¥記法より 古いかも。

[ メッセージ編集済み 編集者: MMX 編集日時 2004-08-23 09:50 ]
佐々木
大ベテラン
会議室デビュー日: 2003/03/30
投稿数: 121
投稿日時: 2004-08-19 17:00
引用:

hihiさんの書き込み (2004-08-19 16:19) より:
"aa","s"f","ss,12"文字列を[aa] [s"f] [ss,12]に個々のデータを抽出したい。



ええと。
* フィールドは必ずダブルクォートで括られている。
* フィールド区切りのカンマの前後にスペースはない。
と多少限定させてもらった上で。

"(.*?(?<!\\))",?

というパターンで文字列の中を進んでいけばフィールドの内容を拾っていけるでしょう。

ただし、拾ったあと、「\"」を「"」に直してやる必要がありますかな。

こんなPerlコードで動作を確認してます。すみませんJavaじゃなくて。
やっぱ正規表現をさくっと試すにはPerl等の「正規表現リテラル」を
認識する言語のほうがやりやすいです。

コード:

my $csv = q/"aa","s\"f","ss,12"/;

while ($csv =~ /"(.*?(?<!\\))",?/g) {
print "[$1]\n";
}



[ メッセージ編集済み 編集者: 佐々木 編集日時 2004-08-19 17:03 ]
未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2004-08-19 17:01
ちょっと自信ないのですが(あくまでご参考。。。)
コード:

Pattern P = Pattern.compile("\"([^\\\\\"]*)\"");
Matcher m = P.matcher(string);
string = m.replaceAll("[$1]");



[ メッセージ編集済み 編集者: Ken-Lab 編集日時 2004-08-19 17:07 ]
・・・と思ったらカンマを抜き忘れたので読み飛ばしといてください。 (^^;

[ メッセージ編集済み 編集者: Ken-Lab 編集日時 2004-08-19 17:13 ]
佐々木
大ベテラン
会議室デビュー日: 2003/03/30
投稿数: 121
投稿日時: 2004-08-19 17:23
引用:
こんなPerlコードで動作を確認してます。すみませんJavaじゃなくて。



Javaでも書いてみました。

コード:
        Pattern p = Pattern.compile("\"(.*?(?<!\\\\))\",?");
        Matcher m = p.matcher("\"aa\",\"s\\\"f\",\"ss,12\"");

        while (m.find()) {
            System.out.println("[" + m.group(1) + "]");
        }



Javaにも「メタ文字を解釈しない文字列リテラル」とか「文字列リテラルのクォート記号を任意に選べる機能」が欲しいですねぇ。

正規表現が"\"だらけになっちゃうんですよね。
hihi
常連さん
会議室デビュー日: 2002/08/30
投稿数: 29
お住まい・勤務地: 名古屋
投稿日時: 2004-08-19 18:02
佐々木さん:
ありがとうございます、その方法で問題を解決しました。
がるがる
ぬし
会議室デビュー日: 2002/04/12
投稿数: 873
投稿日時: 2004-08-19 18:16
どもでし。がるともうします。
んと、ものすごく余談で申し訳ないのですが。
引用:

"aa","s\"f","ss,12"文字列を[aa] [s"f] [ss,12]に


しっているCSVの実装系のほとんどで、[aa] [s"f] [ss,12]の
三つのデータを記述する場合って
aa,"s""f","ss,12"
だと思うですが。もう少し具体的には「データ中の"は、"の二重
であらわす」のが多いパターンだと思うです。

¥(バックスラッシュ)でエスケープするパターンというのは、
Javaでは普通に行われてるパターンなんでしょうか?

JavaでのCSVで、"をあらわすのに上記のように"の二重であらわすと、
なにか問題とか起きるでしょうか?

いあ、単純に興味があって気になったもので。


シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2004-08-19 18:30
引用:

がるがるさんの書き込み (2004-08-19 18:16) より:
しっているCSVの実装系のほとんどで、[aa] [s"f] [ss,12]の
三つのデータを記述する場合って
aa,"s""f","ss,12"
だと思うですが。もう少し具体的には「データ中の"は、"の二重
であらわす」のが多いパターンだと思うです。



Microsoft Excelが入出力を行うCSVファイルのフォーマットがそうなって
いますね。それゆえに、それが事実上の標準になっている?ということでし
ょうか。そもそもCSVフォーマットって標準化はされていなかったような…

引用:

JavaでのCSVで、"をあらわすのに上記のように"の二重であらわすと、
なにか問題とか起きるでしょうか?



そのようなフォーマットに対して適切なパーサ/ジェネレータを作って
あるならば、どのような言語を利用するにしても問題はないかと思い
ますが…

#曖昧なフォーマット定義になるのが嫌でXMLに逃げたくなることもある
#のですが、如何せんユーザの方々はCSVを入出力にすることを望むこと
#が多いので、難しいところです。Excel万歳。

[ メッセージ編集済み 編集者: シュン 編集日時 2004-08-19 19:02 ]

スキルアップ/キャリアアップ(JOB@IT)