ServiceNow開発部ブログ第8回目です。
カンマ区切りされた文字列を配列に変換する方法として split 関数が使えます。しかし、それだけでは 12,345 のような桁区切りのある金額などには対応できません。そこで、引用符で囲まれたカンマ記号も考慮して配列に変換する方法を検討しました。
下記を使用してconvertListToArray 関数を作成しました。
- 文字列の先頭や最後に特定の文字・記号が存在するかどうかを調べる startsWith および endsWith 関数
- 文字列から一部分を切り抜く slice 関数
さらに、splitMark および quoteMark の値を変更することにより、カンマ以外の区切り方に対応したり、引用符の種類を変更可能です。
function convertListToArray(str) {
var res = []; //結果配列
var resIdx = 0;
var splitMark = ','; //区切り記号
var quoteMark = '"'; //引用記号
var wrk = []; //作業用
var quoted = false; //引用符で始まり、まだ閉じられていない場合 true
wrk = str.split(splitMark);
for (key in wrk) {
if (quoted) {
if (wrk[key].endsWith(quoteMark)) {
//引用符で閉じられました
res[resIdx] += splitMark + wrk[key].slice(0, -1);
resIdx++;
quoted = false;
} else {
//引用符で閉じられるまで文字列連結
res[resIdx] += splitMark + wrk[key];
}
} else {
if (wrk[key].startsWith(quoteMark) && !wrk[key].endsWith(quoteMark)) {
//引用符で始まり、閉じられていません
res[resIdx] = wrk[key].slice(1);
quoted = true;
} else if (wrk[key].startsWith(quoteMark) && wrk[key].endsWith(quoteMark)) {
//引用符で囲まれています
res[resIdx] = wrk[key].slice(1, -1);
resIdx++;
} else {
res[resIdx] = wrk[key];
resIdx++;
}
}
}
//引用符の開始と終了がペアになるので、処理正常なら false になっているはず。
if (quoted) {
gs.error("引用符が閉じられませんでした");
}
return res;
};
下記のようなリストを渡した場合の結果を掲載します。
var str = '34,, ,"4,567"," f,dfd "," ","",2.3,/"54/",456,';//テストしたい文字列 var res = convertListToArray(str); //結果確認 for (key2 in res) { gs.info(">" + res[key2] + "<"); }; //結果 //*** Script: >34< //*** Script: >< //*** Script: > < //*** Script: >4,567< //*** Script: > f,dfd < //*** Script: > < //*** Script: >< //*** Script: >2.3< //*** Script: >/"54/"< //*** Script: >456< //*** Script: ><
引用符で囲まれた数値(桁区切りあり)ばかりではなく、引用符がエスケープされている場合などもリストを配列に変換できるようになりました。
上記で示したコードのほか、文字コードのチェック、ファイル内容を改行ごとに分割する処理、ヘッダ部分の処理などを追加すると、CSVファイルを取り込むことができるようになります。