2017-10-09 510 views
1

我正試圖在NetSuite中生成一個包含30,000多個項目的Google購物Feed,該系統運行稱爲Suitescript 2.0的服務器端JavaScript。從本質上講,它只是帶有更多限制的JavaScript。我一直負責將此產品Feed作爲CSV輸出。將包含逗號和雙引號的字符串寫入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項...

有誰知道可能會在這裏嗎?我覺得有一些很簡單的東西可以忽略...

+0

如果你避開功能應該反斜槓添加到輸出,你需要逃避反斜槓在字符串中函數中的文字,即「\\,」而不是「\ \」,或者是包含單引號的文字,或者是'''''或者''\\'「'。 – nnnnnn

+0

不,它不應該添加反斜槓。這只是爲了逃避他們的最後一個字符串。添加溢出的反斜槓會使事情再次失靈,並且不會添加新行,但會將其附加到包含引號的行的末尾...... – B1gJ4k3

+0

什麼是「爲了最終字符串而逃脫它們」對您意味着什麼?這是不是說最終的字符串會添加反斜槓?例如,如果特定*字段*的輸入是「你好,再見」,那麼輸出應該是「你好\,再見」,不是嗎?對於CSV,假設你正在刪除換行符並將每個字段放在雙引號中,我認爲只有雙引號需要被轉義 - 雖然由於某種原因,您似乎將整個*行*放在雙引號中,這對CSV來說不正常。請[編輯]您的問題,以顯示一個示例兩行輸入和相應的期望輸出。 – nnnnnn

回答

1

事實證明,根據CSV specs,要在已經引用的字符串中包含雙引號,您需要使用兩個雙引號(「」 )。我改變:

itemDesc = itemDesc.replace(/"/g, '\"'); 

itemDesc = itemDesc.replace(/"/g, '""'); 

我也刪除

itemDesc = itemDesc.replace(/,/g, '\,'); 
itemDesc = itemDesc.replace(/'/g, '\''); 

由於在CSV列被已經引用。這些是不必要的。

0

我使用這個簡單的函數將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'); 
} 
相關問題