I needed something like this today so I found snippet originally done by by Bennadel and cleaned it up a bit also adding in edge cases.
/*
* shortened version of:
* http://www.bennadel.com/blog/1504-ask-ben-parsing-csv-strings-with-javascript-exec-regular-expression-command.htm
*
* Supports columns that are quoted/non-quoted. Takes care of quoted columns that may also have \n's inside
* them instead of using a naive approach of split('\n')
*
* @param csvString {string} CSV file of rows separated by new lines.
* @param delimiter {string} delimiter used to split columns
*
* return {rows} Array of rows with columns containing parsed CSV data
*/
function CSVParse(csvString, delimiter = ",") {
if (!csvString || !csvString.length)
return [];
const pattern = new RegExp(
( "(\\" + delimiter + "|\\r?\\n|\\r|^)" +
"(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +
"([^\"\\" + delimiter + "\\r\\n]*))"
), "gi"
);
let rows = [[]];
let matches = false;
while (matches = pattern.exec(csvString)) {
const matched_delimiter = matches[1];
const matched_cellQuote = matches[2];
const matched_cellNoQuote = matches[3];
/*
* Edge case: Data that starts with a delimiter
*/
if (matches.index == 0 && matched_delimiter)
rows[rows.length - 1].push("");
/*
* Fix empty lines
*/
if(!matches[2] && !matches[3])
continue;
if (matched_delimiter.length && matched_delimiter !== delimiter)
rows.push([]);
const matched_value = (matched_cellQuote)
? matched_cellQuote.replace(
new RegExp("\"\"", "g"), "\""
)
: matched_cellNoQuote;
rows[rows.length - 1].push(matched_value);
}
return rows;
}