如何使用JavaScript解析字段中包含换行符的CSV数据

如何使用JavaScript解析字段中包含换行符的CSV数据,javascript,regex,node.js,parsing,csv,Javascript,Regex,Node.js,Parsing,Csv,给定在某些字段中具有换行符/返回字符的CSV文件,我们如何在不将字段拆分为多行的情况下解析数据 CSV数据示例: ID;Name;Country;ISO-2;Address;Latitude;Longitude 022wje3;Europa;Italy;IT;"Viale Kennedy 3 34073 Grado";"45,67960";"13,40070" 024oua5;Hiberia;Italy;IT;"Via XXIV Maggio 8 00187 Rome";"41,89720";"

给定在某些字段中具有换行符/返回字符的CSV文件,我们如何在不将字段拆分为多行的情况下解析数据

CSV数据示例:

ID;Name;Country;ISO-2;Address;Latitude;Longitude
022wje3;Europa;Italy;IT;"Viale Kennedy 3
34073 Grado";"45,67960";"13,40070"
024oua5;Hiberia;Italy;IT;"Via XXIV Maggio 8
00187 Rome";"41,89720";"12,48680"
028gupn;Regal Riverside;Hong Kong;HK;"34-36 Tai Chung Kiu Road
Shatin
Hong Kong";"22,38260";"114,19600"
02j7qry;Okaliptus Holiday Villas Apart;Turkey;TR;"Sevket Sabanci Caddesi No. 70
Bahçelievler Mevkii
Turgutreis";"37,02130";"27,25120"
02pc99z;California Apartementos;Spain;ES;"Prat d'en Carbó
43840 Salou";"41,07620";"1,14667"
02tu1jz;Elvis Presley's Heartbreak;United States;US;"3677 Elvis Presley Blvd.
Memphis
Tennessee 38116";"35,04850";"-90,02710"
注意:字段实际上用分号分隔
因为地址可以包含逗号

每行有7个字段,但我们不希望将包含换行符的字段中的数据错误地解析为多行

我们在StackOverflow上找到了几个以Perl为中心的答案:

但我对Perl有点生疏,还没有找到一个专注于JS的答案

你试过本·纳德尔的作品吗

/**
 * CSVToArray parses any String of Data including '\r' '\n' characters,
 * and returns an array with the rows of data.
 * @param {String} CSV_string - the CSV string you need to parse
 * @param {String} delimiter - the delimeter used to separate fields of data
 * @returns {Array} rows - rows of CSV where first row are column headers
 */
function CSVToArray (CSV_string, delimiter) {
   delimiter = (delimiter || ","); // user-supplied delimeter or default comma

   var pattern = new RegExp( // regular expression to parse the CSV values.
     ( // Delimiters:
       "(\\" + delimiter + "|\\r?\\n|\\r|^)" +
       // Quoted fields.
       "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +
       // Standard fields.
       "([^\"\\" + delimiter + "\\r\\n]*))"
     ), "gi"
   );

   var rows = [[]];  // array to hold our data. First row is column headers.
   // array to hold our individual pattern matching groups:
   var matches = false; // false if we don't find any matches
   // Loop until we no longer find a regular expression match
   while (matches = pattern.exec( CSV_string )) {
       var matched_delimiter = matches[1]; // Get the matched delimiter
       // Check if the delimiter has a length (and is not the start of string)
       // and if it matches field delimiter. If not, it is a row delimiter.
       if (matched_delimiter.length && matched_delimiter !== delimiter) {
         // Since this is a new row of data, add an empty row to the array.
         rows.push( [] );
       }
       var matched_value;
       // Once we have eliminated the delimiter, check to see
       // what kind of value was captured (quoted or unquoted):
       if (matches[2]) { // found quoted value. unescape any double quotes.
        matched_value = matches[2].replace(
          new RegExp( "\"\"", "g" ), "\""
        );
       } else { // found a non-quoted value
         matched_value = matches[3];
       }
       // Now that we have our value string, let's add
       // it to the data array.
       rows[rows.length - 1].push(matched_value);
   }
   return rows; // Return the parsed data Array
}
在您的情况下,使用以下命令调用它:

var rows = CSVToArray(CSV_string, ';');

其中
CSV\u string
是您的CSV数据字符串。

有点晚了,但我希望它能帮助别人

不久前,我甚至遇到了一个类似的问题,我在我的angular项目中使用了一个库

您可以使用以下代码将CSV文件作为字符串读取,然后将该字符串传递给csvtojson库,它将为您提供一个JSON列表

示例代码:

const csv=require('csvtojson');
如果(files&&files.length>0){
常量文件:文件=文件。项(0);
常量读取器:FileReader=newfilereader();
reader.readAsText(文件);
reader.onload=(e)=>{
const csvs:string=reader.result作为字符串;
csv({
输出:“json”,
noheader:false
}).fromString(csvs)
.preFileLine((文件行,idx)=>{
//在将csv文件解析为json之前,将csv头行转换为小写
if(idx==0){return fileLine.toLowerCase()}
返回文件行;
})
。然后((结果)=>{
//结果中的json列表
});
}
}
}

用双引号括起来的换行符不是记录的结尾。你是从那些Perl链接中得到的吗?而且,如果你不明白Ben Nadel是怎么做到的,你就不知道如何为非标准案例做正则表达式。最好搜索csv解析正则表达式。我自己也发了不少。双引号内的新行仍然是同一行/字段。我想我已经理解了CSVToArray,它解决了我们眼前的问题。我会通读你的一些正则表达式的答案来复习。谢谢有没有一种方法可以同时获取单个单元格?很抱歉来晚了:这很好,除非分隔符是制表符:知道如何处理吗?