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

お世話になります。

csvファイルを文字列としてロード後、二次元配列に格納して利用するプログラムを作成しております。
こちらの
http://tips.recatnap.info/wiki/JQuery%E3%81%A7CS …
jquery.csv.jsというプラグインでCSVファイルを配列に格納してみたのですが、セル内の文字列に改行がある場合は対応していないようで、データが崩れてしまいました。

いろいろ調べたところ、単なるsplitでは上手くいかないということや、ダブルクオートが閉じられていない改行コードはレコードの最後だとはみなさないようにすればいいなど、イメージとしてはわかるのですが、検索してもそのような手本となるようなサンプルやjquery.csv.jsの改造方法などが見つけられませんでした。

自分ではどう記述したらいいのかさっぱりわからず、皆様のお力をお借りしたいと思います。

必要な情報があれば補足いたしますので、
なにとぞよろしくお願いいたします。

A 回答 (2件)

字句解析と構文解析を行う必要があります。


この手はコンパイラ技術の範疇なので、面倒に思えるかもしれませんが、
CSV程度に用いるならたいしたことはありません。

以下簡単なサンプルです

// 字句解析
function Tokenizer(src) {
this.src = src;
this.index = 0;
this.length = src.length;
}
Tokenizer.prototype = {
seekC: function(){ return (this.index < this.length)? this.src.charCodeAt(this.index): 0 },
readC: function(){ var i = this.index++; return (i < this.length)? this.src.charCodeAt(i): 0 },
forwC: function(){ this.index++ },
backC: function(){ this.index-- },
readS: function (eoc){
var s = '', x = this.readC();
while (x) {
if (x == eoc) { if (this.seekC() == eoc) this.forwC(); else break; }
s += String.fromCharCode(x);
x = this.readC();
}
return s;
},
TASK: {
0x00: function(c){ return {type:'eof'} },
0x0A: function(c){ return {type:'eol'} },
0x0D: function(c){ if (this.seekC() == 0x0A) this.forwC(); return {type:'eol'} },
0x22: function(c){ return {type:'string', body:this.readS(0x22)} },
0x27: function(c){ return {type:'string', body:this.readS(0x27)} },
0x2C: function(c){ return {type:'separator'} },
},
nextToken: function(){
var c = this.readC(), f = this.TASK[c];
if (f) return f.call(this, c);
var s = String.fromCharCode(c);
for (c = this.seekC(); !this.TASK[c]; c = this.seekC()) s += String.fromCharCode(this.readC());
return {type:'string', body:s};
}
};

// 構文解析
function parseCSV(text) {
var pre, tok, t = new Tokenizer(text), flag = true;
var records = [], record = [], s = '';
while (flag) {
tok = t.nextToken();
switch (tok.type) {
case 'string':
s += tok.body;
break;
case 'separator':
record.push(s), s = '';
break;
case 'eof':
flag = false;
if (pre.type != 'eol') {
record.push(s), s = '';
records.push(record), record = [];
}
break;
case 'eol':
record.push(s), s = '';
records.push(record), record = [];
break;
default:
throw "error!";
}
pre = tok;
}
return records;
}

// 使用例
var data = parseCSV("abc,'def','g h i'\n'jk''lmn''op','qrs\ntu',vwxyz");
    • good
    • 0
この回答へのお礼

わざわざサンプルを書いて頂きましてありがとうございます。
最初書いて頂いた内容を参考に作ろうと思っていましたが、ちょうど良いライブラリを配布なさっている方がいらっしゃいましたので、今回はそちら一部参考にして無事思い通りの動作をさせることができました。
今回はこちらのライブラリを参考にしてできそうなので、こちらを利用させて頂こうと思います。
http://www.kawa.net/works/js/jkl/parsexml.html

ありがとうございました。

お礼日時:2015/06/04 00:47

「詳しい人」ではありませんので、ご希望とは違ってしまってますが




◆自作するのに、考え方やロジックを求めているのなら…

規格が一応あるようですが後付け的なので、csv作成のアプリケーションによって独自のルールで作成されている場合があるようです。
 http://www.kasai.fm/wiki/rfc4180jp

以下のサイトに概略の考え方やコード例(javascriptではありませんが)も示されていますので、ご参考になるかと思います。
 http://dobon.net/vb/dotnet/file/readcsvfile.html

すでに調べていらっしゃるかも知れませんが、ご質問内容はそれなりに一般的なものなので、いろいろと取り組んでいる先人達がたくさんいると思われます。
検索すれば、上記以外にも解説しているサイトは数多くあることでしょう。


◆自作するわけではなく、変換できさえすればよいのなら…

同様に、ライブラリ化されているものも多くあるようですので、それを利用するのが簡単かと。
吟味していませんが、とりあえず検索してみたもの。
 http://papaparse.com/
 http://jquery-csv.googlecode.com/git/examples/ba …

ちゃんと探せば、こちらも数多く見つかると思いますので、ご希望に合うものをご利用なさるのがよろしいでしょう。
    • good
    • 0
この回答へのお礼

ありがとうございます。

今回はできればそのまま使えるライブラリを探していたのですが、日本語でばかり検索していたので見つけられませんでした。今後の参考にさせて頂きます。

今回はこちらのライブラリを参考にしてできそうなので、こちらを利用させて頂こうと思います。
http://www.kawa.net/works/js/jkl/parsexml.html

お礼日時:2015/06/04 00:44

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