challenge RFC 4180対応版 CSVレコードの分解

ある関数(splitCSV)に渡された文字列を配列に分解して列ごとに表示してください。
渡される文字列は、CSVデータの1レコードが設定されているとします。

使用するデータはK3形式が元になっている仕様で
エクセルが出力しているような形式です。

書式には次のような特徴があります。
1. 各レコードは「改行」によって区切られている。
2. 各列は「,」によって区切られている。
3. 列のデータは「"」によって囲んでも良い。
4. 列に「,」「改行」「"」いずれかを含む場合「"」で
   囲わなければならない。
5. 列データに「"」を含める場合「""」とする。

本来、改行コードはCRLFですが今回は特に指定しません。

次の入力があった場合
"aaa","b
bb","ccc",zzz,"y""Y""y",xxx

出力は
1 => aaa
2 => b
bb
3 => ccc
4 => zzz
5 => y"Y"y
6 => xxx

となります。
このお題はraynstardさんの投稿によるものです。ご投稿ありがとうございます。助かります。

Posted feedbacks - JavaScript

JavaScriptでの投稿が無いようなので。ちょっと修正すれば複数レコードのパーズも対応できるはず。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function unquote(val) {
  return (val.indexOf('"') == 0) ? val.substring(1, val.length-1).replace(/""/g, '"')
                                 : val;
}
function splitCsv(csv) {
  // カラム分離用パターン
  //   グループ1⇒ 行頭 or カンマ or 改行
  //   グループ2⇒ 空文字列 or 非quoted文字列 or quoted文字列
  //     非quoted文字列⇒ 改行, カンマ, " を含まない1文字 +
  //                     改行, カンマを含まない文字を0文字以上
  //     quoted文字列⇒ " + ( "" or " 以外の1文字 ) を0回以上 + "
  //   (?=,|\\r?\\n|$)⇒ 次に カンマ, 改行, 行末が続くこと(幅0肯定先読み)
  var reg = new RegExp('(^|,|\\r?\\n)(|[^"\\r\\n,][^\\r\\n,]*|(?:"(?:""|[^"])*"))(?=,|\\r?\\n|$)', 'g');

  var ary = [];
  var match = null;
  while(match = reg.exec(csv)) {
    ary.push(unquote(match[2]));
  }
  return ary;
}

function printCsv(input) {
  var values = splitCsv(input);
  var ary = [];

  for(var i=0; i<values.length; i++) {
    ary.push((i+1) + ' => ' + values[i]);
  }
  alert(ary.join("\n"));
}

printCsv('"aaa","b\n\
bb","ccc",zzz,"y""Y""y",xxx');

Index

Feed

Other

Link

Pathtraq

loading...