ugnagブログ

たいした内容はありません。思いつきで書いているだけ。
開発日記がメインかな。

<< ようやく回復 | main | パワーポイントVBA >>

CSV解析スクリプト

JavaScript用のクラス
まだデバッグしていないので、動作未確認。

CSVには明確なルールがないようなので困るが、解析ルールとして
エクセルを基準にしてみた。

特に例外的な処理をどうするかだ。


試してわかったのは、

1.行頭または、カンマの直後がDQ(ダブルコーテーション)以外なら、囲み無しと判断。
2.囲みなしのフィールドはカンマが出てくるまでがそのフィールド。
 DQが出てきても、何も考えずに単なる文字として処理する。
3.囲みありの場合、フィールドの終わりは、単体のDQ後のカンマまでとなる。
単体のDQ(囲みの終わり)の前に出現する連続したDQは1つのDQに置き換える。
単体のDQからカンマまでに出てきた文字は、囲み無しと同じ処理。


というルールのようである。

これに沿ってスクリプトを作った。

後でコメント欄に貼り付けておこう。
プログラム・開発(その他開発) | comments (1) | -

Comments

| 2010/03/25 01:02 PM
<html>
<head>
<script type="text/JavaScript">




function CsvParser()
{
this.unknown = 0;
this.non_dq = 1;
this.dq_open = 2;
this.dq_closed = 3;

this.ix = -1;
this.line = '';
this.state = this.non_dq;
this.eol = false;

this.setText = function(text){

this.state = this.unknwon;
this.line = text;
this.eol = false;
this.ix = 0;

}


/** 指定された文字列を解析し、csvのルールに従った項目分解を行う
* @param text 項目分解を行う文字列
* @return 項目ごとに配列で分解された文字列
*/
this.parse = function(text){

//オブジェクトの初期化
this.setText(text);

//項目ごとに配列に追加
var item;
var ary = new Array(0);
item = this.getNextField();
while(item != null){
this.addItemToArray(ary, item);
item = this.getNextField();
}

return ary;

}



/** 次の項目を取得する
*/
this.getNextField = function(){

//末尾判定
if(this.eol){
return null;
}

//フィールド状態の初期化
this.state = this.unknwon;
var item = '';
var c;
c = this.getChar();
while(c != null){
item += c;
c = this.getChar();
}

return item;

}




/** 指定された配列にオブジェクトを追加する
*/
this.addItemToArray = function(ary, itm){

var n = ary.length;
ary.length = n + 1;
ary[n] = itm;

}



/** 文字取得
*/
this.getLetter = function(){

if(this.line.length <= this.ix){
this.eol = true;
return null;
}

var c = this.line.charAt(this.ix);
this.ix++;

return c;

}


/** 文字取得
*/
this.scanLetter = function(){

if(this.line.length <= this.ix){
return null;
}

var c = this.line.charAt(this.ix);

return c;

}



/** 文字取得
*/
this.getChar = function(){

var c;

c = this.getLetter();

if(this.state == this.unknwon){
if(c == '"'){
this.state = this.dq_open;
c = this.getChar();
return c;
}else{
this.state = this.non_dq;
if(c == ','){
return null;
}
return c;
}
}else
if(this.state == this.non_dq){
if(c == ','){
return null;
}
return c;
}else
if(this.state == this.dq_open){
if(c == '"'){
var c2 = this.scanLetter();
if(c2 == '"'){
this.getLetter();
return '"';
}else{
this.state = this.dq_closed;
c = this.getChar();
return c;
}
}
return c;
}else
if(this.state == this.dq_closed){
if(c == ','){
return null;
}
return c;
}


}

}



var csv = new CsvParser();




function go()
{
var tx = document.getElementById('tx1');
var ta = document.getElementById('ta1');

var parts = csv.parse(tx.value);

var txt = '';
for(var i = 0 ; i < parts.length ; i++){
txt += ('[' + parts[i] + ']\n');
}
ta.value = txt;


}




</script>
</head>
<body style="background:#e0e0e0">

<input type="button" value="再読込" onclick="location.reload();">

<input type="text" id="tx1" value="ab,cd">
<input type="button" onclick="go();">
<textarea id="ta1" rows="20"></textarea>




</body>
</html>

Comment Form

本文に書いて下さい
本文にh抜きで書いて下さい