トラブルの内容
javascriptでsplitを使ってコンマで分割すると、""で囲まれた内部のコンマまで分割されてしまう。
動作環境
Mac OS、Windows10
node v12.15.0
追記
SalesforceのLightning Web Component(LWC)でのJavascriptの記事です。LWC以外のJavascriptのコードをとして利用する場合は、コードを変更する必要があります。(functionの有無とか) また、コメント欄での指摘も参考にして下さい。また、タイトルに対するより完成度の高いコードを知りたい場合は以下のページを参考にして下さい。
https://qiita.com/noenture/items/02b2e1711e22182c6a97
結論
Webサイトを参考にしてJavaの関数をJavascriptに翻訳することで解決しました。正規表現では解決は出来ませんでした。
以下、解決への過程
まず次のWebサイトを参考にしました。
人力検索はてな javascriptでsplitを使ってコンマで分割すると、""で囲まれた内部のコンマまで分割されてしまいます。きれいにCSVに分割する方法を教えてください
しかし、このページの回答では、自分のCSVを目的どおりに分割することはできませんでした。自分の場合、以下のようなCSVファイルを分割したいという目的でした。
あいうえお太郎,25歳,"¥1,500",東京都
かきくけこ花子,24歳,"¥1,200",さいたま県
FileMakerで出力したExcel形式のファイルをCSVに変換すると、このように金額の部分にカンマが付くので、明示的にダブルクォーテーションで囲まれます。このようなCSVを分割した場合に"¥1,500"が"¥1と500"に分かれてしまう。というトラブルを解決したかったのですが、このページに書かれている正規表現ではうまくいきませんでした。
このため、上記サイトの正規表現での解決は諦めて別のWebサイトの方法に頼ることにしました。次に参考にしたのはこのページでした。
Qiita CSVファイルにカンマの含まれる項目を分割せずに読み込む(Java)
タイトルの通り、Javaで書かれていましたが、このページに書かれているJavaのコードをJavascriptに翻訳して実行したら解決しましたというのが自分の解決方法です。以下、Javascriptのコードを記載します。
/**
* CSVの一行を引数に指定すると、
* ""で囲まれた内部のコンマを分割せずに、
* コンマで分割して配列の戻り値を返す関数
* @param {string} line 文字列
* @return {Array<string>} 配列
*/
csvSplit(line) {
var c = "";
var s = new String();
var data = new Array();
var singleQuoteFlg = false;
for (var i = 0; i < line.length; i++) {
c = line.charAt(i);
if (c == "," && !singleQuoteFlg) {
data.push(s.toString());
s = "";
} else if (c == "," && singleQuoteFlg) {
s = s + c;
} else if (c == '"') {
singleQuoteFlg = !singleQuoteFlg;
} else {
s = s + c;
}
}
return data;
}
- 上記の関数をLWC(Lightning Web Component)のクラスの中にメソッドとしてコピペしてください。
上記csvSplit関数の呼び出し側のコード
- めんどくさがり屋の人のために上記csvSplit関数の呼び出し側のコードも載せておきます。
// CSVで取得したデータを行ごとに配列にしたものをfor文で処理している。
for (var i = 1; i < csvArray.length - 1; i++) {
// カンマで区切られた各データに分割する(これだと、""がある場合ダメ)
//var csvArrayD = csvArray[i].split(",");
// ""で囲まれた内部のコンマまで分割されてしまうのを回避
var csvArrayD = this.csvSplit(csvArray[i]);
}
解説をすると、普通はsplit(",")でCSVをカンマで分割して配列に代入するという処理でも問題ないのですが、読み込むCSVの内容によっては、「""で囲まれた内部のコンマを分割せずに」処理しないといけない場合があります。このような場合は、this.csvSplit("CSVの行")というように上記の関数を呼び出して実行することで解決できます。for文が気に入らない人など、ここら辺のコードについては、各自の環境・センスに合わせて修正して下さい。
以上です。Good Luck!