将包含逗号和双引号的字符串写入CSV

B1g*_*4k3 10 javascript csv comma double-quotes suitescript2.0

我正在尝试在NetSuite中生成一个包含30,000多个项目的Google购物Feed,这是一个运行服务器端JavaScript的CRM系统,它称之为Suitescript 2.0.从本质上讲,它只是JavaScript的一些限制.我的任务是将此产品Feed输出为CSV格式.

问题是这些项目的产品描述包含逗号,双引号,单引号和HTML的变量.起初,只是逗号引起了我的问题,所以在经过一些研究之后,我用双引号输出了我输出的字符串:

//This function isn't terribly important, but is referenced below

function sanitizeString (desc) {
    var itemDesc;
    if (desc) {
        itemDesc = desc.replace(/(\r\n|\n|\r|\s+|\t| )/gm,' ');
        itemDesc = itemDesc.replace(/,/g, '\,');
        itemDesc = itemDesc.replace(/"/g, '\"');
        itemDesc = itemDesc.replace(/'/g, '\'');
        itemDesc = itemDesc.replace(/ +(?= )/g,'');
    } else {
        itemDesc = '';
    }
    return itemDesc;
}

var row = '';

for (var i = 0; i < columns.length; i++) {
    var col = columns[i];
    row += '"' + sanitizeString(val[col]) + '"';
    if (i != columns.length - 1) {
        row += ',';
    }
}
newFeed.appendLine({value: row});
Run Code Online (Sandbox Code Playgroud)

但是,似乎这些双引号与字符串中的双引号奇怪地交互,导致一些奇怪的格式化,即使我的sanitizeString()函数应该转义它们.只要描述包含双引号,下一行就不会获得它自己的行.它会附加到最后一列.

所以,很自然地,我逃脱了这样的外部引号:

row += '\"' + sanitizeString(val[col]) + '\"';
Run Code Online (Sandbox Code Playgroud)

这样做会让事情变得完全失控,很多项目都没有被推到新的行,我最大限度地增加了我允许的列数,因为它一直在继续.

另一个自然的解决方案是编辑产品描述,但我并不十分渴望为30,000多件商品做到这一点......

有谁知道这里会发生什么?我觉得有一些非常简单的东西我会忽略......

B1g*_*4k3 14

事实证明,根据CSV规范,要在已引用的字符串中包含双引号,您需要使用两个双引号("").我变了:

itemDesc = itemDesc.replace(/"/g, '\"');
Run Code Online (Sandbox Code Playgroud)

itemDesc = itemDesc.replace(/"/g, '""');
Run Code Online (Sandbox Code Playgroud)

我也删除了

itemDesc = itemDesc.replace(/,/g, '\,');
itemDesc = itemDesc.replace(/'/g, '\'');
Run Code Online (Sandbox Code Playgroud)

由于CSV中的列已被引用.这些是不必要的.

  • 边缘情况,如果字符串不以引号开头,它可以包含转义引号,例如 `Yes "" I am`。如果它以引号开头,则必须以引号结尾。即使术语没有被引用,引号也必须被转义。乐趣。 (2认同)

Mic*_*arf 5

我使用这个简单的函数将 an 转换string[][]为 csv 文件。如果单元格包含"、 a,或其他空格(空格除外),它会引用该单元格:

/**
 * Takes an array of arrays and returns a `,` sparated csv file.
 * @param {string[][]} table
 * @returns {string}
 */
export function toCSV(table: string[][]) {
    return table
        .map(row =>
            row
                .map(cell => {
                    // We remove blanks and check if the column contains
                    // other whitespace,`,` or `"`.
                    // In that case, we need to quote the column.
                    if (cell.replace(/ /g, '').match(/[\s,"]/)) {
                        return '"' + cell.replace(/"/g, '""') + '"';
                    }
                    return cell;
                })
                .join(',')
        )
        .join('\n');
}
Run Code Online (Sandbox Code Playgroud)