将包含逗号和双引号的字符串写入 CSV
Write a string containing commas and double quotes to CSV
我正在尝试在 NetSuite 中生成一个 Google 包含 30,000 多件商品的购物提要,NetSuite 是一个运行服务器端 JavaScript 的 CRM 系统,它称为 Suitescript 2.0。本质上,它只是 JavaScript 加上一些限制。我的任务是将此产品提要输出为 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});
但是,这些双引号似乎与字符串中的双引号奇怪地相互作用,导致一些奇怪的格式,即使我的 sanitizeString() 函数应该转义它们。任何时候描述包含双引号时,下一行都不会单独占一行。它被附加到最后一列。
所以,自然地,我像这样转义了外部引号:
row += '\"' + sanitizeString(val[col]) + '\"';
这样做会让事情变得一团糟,很多项目不会被推到新的行,而且我最大限度地增加了我允许的列数,因为它一直在继续。
另一个自然的解决方案是编辑产品说明,但我并不急于为 30,000 多件商品这样做...
有人知道这里会发生什么吗?我觉得我忽略了一些非常简单的事情...
事实证明,根据 CSV specs,要在已引用的字符串中包含双引号,您需要使用两个双引号 ("")。我改变了:
itemDesc = itemDesc.replace(/"/g, '\"');
到
itemDesc = itemDesc.replace(/"/g, '""');
我也删除了
itemDesc = itemDesc.replace(/,/g, '\,');
itemDesc = itemDesc.replace(/'/g, '\'');
因为 CSV 中的列已被引用。这些都是不必要的。
我使用这个简单的函数将 string[][]
转换为 csv 文件。它引用单元格,如果它包含 "
、,
或其他空格(空格除外):
/**
* 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');
}
就我而言,我不想引用不需要引用的字符串。所以我在引用它之前测试了字符串中是否有讨厌的字符。
function escapeCSV (term) {
if (term.match && term.match(/,|"/)) {
return `"${term.replace('"','""')}"`
} else {
return term
}
}
我正在尝试在 NetSuite 中生成一个 Google 包含 30,000 多件商品的购物提要,NetSuite 是一个运行服务器端 JavaScript 的 CRM 系统,它称为 Suitescript 2.0。本质上,它只是 JavaScript 加上一些限制。我的任务是将此产品提要输出为 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});
但是,这些双引号似乎与字符串中的双引号奇怪地相互作用,导致一些奇怪的格式,即使我的 sanitizeString() 函数应该转义它们。任何时候描述包含双引号时,下一行都不会单独占一行。它被附加到最后一列。
所以,自然地,我像这样转义了外部引号:
row += '\"' + sanitizeString(val[col]) + '\"';
这样做会让事情变得一团糟,很多项目不会被推到新的行,而且我最大限度地增加了我允许的列数,因为它一直在继续。
另一个自然的解决方案是编辑产品说明,但我并不急于为 30,000 多件商品这样做...
有人知道这里会发生什么吗?我觉得我忽略了一些非常简单的事情...
事实证明,根据 CSV specs,要在已引用的字符串中包含双引号,您需要使用两个双引号 ("")。我改变了:
itemDesc = itemDesc.replace(/"/g, '\"');
到
itemDesc = itemDesc.replace(/"/g, '""');
我也删除了
itemDesc = itemDesc.replace(/,/g, '\,');
itemDesc = itemDesc.replace(/'/g, '\'');
因为 CSV 中的列已被引用。这些都是不必要的。
我使用这个简单的函数将 string[][]
转换为 csv 文件。它引用单元格,如果它包含 "
、,
或其他空格(空格除外):
/**
* 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');
}
就我而言,我不想引用不需要引用的字符串。所以我在引用它之前测试了字符串中是否有讨厌的字符。
function escapeCSV (term) {
if (term.match && term.match(/,|"/)) {
return `"${term.replace('"','""')}"`
} else {
return term
}
}