用于解析 CSV 数据的示例 JavaScript 代码

Posted

技术标签:

【中文标题】用于解析 CSV 数据的示例 JavaScript 代码【英文标题】:Example JavaScript code to parse CSV data 【发布时间】:2010-11-20 13:24:18 【问题描述】:

在哪里可以找到一些 javascript 代码来解析 CSV 数据?

【问题讨论】:

在这里看看这个答案,它有很好的答案:***.com/questions/8493195/… 下面的大多数答案都是错误的,除了安迪的答案。任何使用模式匹配或拆分的答案都注定要失败——它们不支持转义序列。为此,您需要一个有限状态机。 使用 JavaScript 和 Papa Parse 解析本地 CSV 文件:joyofdata.de/blog/… Papa Parse 是另一个选项,具有很多功能(多线程、标题行支持、自动检测分隔符等) 请注意通过搜索或其他方式看到此内容的人;这不是一个好问题的例子。回到 Stack Overflow 刚开始时,这些类型的问题是被允许的。 【参考方案1】:

您可以使用本博文中提到的CSVToArray() 函数。

<script type="text/javascript">
    // ref: http://***.com/a/1293163/2343
    // This will parse a delimited string into an array of
    // arrays. The default delimiter is the comma, but this
    // can be overriden in the second argument.
    function CSVToArray( strData, strDelimiter )
        // Check to see if the delimiter is defined. If not,
        // then default to comma.
        strDelimiter = (strDelimiter || ",");

        // Create a regular expression to parse the CSV values.
        var objPattern = new RegExp(
            (
                // Delimiters.
                "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +

                // Quoted fields.
                "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +

                // Standard fields.
                "([^\"\\" + strDelimiter + "\\r\\n]*))"
            ),
            "gi"
            );


        // Create an array to hold our data. Give the array
        // a default empty first row.
        var arrData = [[]];

        // Create an array to hold our individual pattern
        // matching groups.
        var arrMatches = null;


        // Keep looping over the regular expression matches
        // until we can no longer find a match.
        while (arrMatches = objPattern.exec( strData ))

            // Get the delimiter that was found.
            var strMatchedDelimiter = arrMatches[ 1 ];

            // Check to see if the given delimiter has a length
            // (is not the start of string) and if it matches
            // field delimiter. If id does not, then we know
            // that this delimiter is a row delimiter.
            if (
                strMatchedDelimiter.length &&
                strMatchedDelimiter !== strDelimiter
                )

                // Since we have reached a new row of data,
                // add an empty row to our data array.
                arrData.push( [] );

            

            var strMatchedValue;

            // Now that we have our delimiter out of the way,
            // let's check to see which kind of value we
            // captured (quoted or unquoted).
            if (arrMatches[ 2 ])

                // We found a quoted value. When we capture
                // this value, unescape any double quotes.
                strMatchedValue = arrMatches[ 2 ].replace(
                    new RegExp( "\"\"", "g" ),
                    "\""
                    );

             else 

                // We found a non-quoted value.
                strMatchedValue = arrMatches[ 3 ];

            


            // Now that we have our value string, let's add
            // it to the data array.
            arrData[ arrData.length - 1 ].push( strMatchedValue );
        

        // Return the parsed data.
        return( arrData );
    

</script>

【讨论】:

它为 引用空字段提供undefined。示例:CSVToArray("4,,6") 给了我[["4","","6"]],但CSVToArray("4,\"\",6") 给了我[["4",undefined,"6"]] 我在 Firefox 中遇到了这个问题,并且脚本变得无响应。不过好像只影响到少数用户,所以找不到原因 正则表达式中有一个错误:"([^\"\\" 应该是"([^\\"。否则,未引用值中任何位置的双引号都会过早地结束它。发现这个很难...... 对于寻求上述方法的简化版本并应用上述正则表达式修复的任何人:gist.github.com/Jezternz/c8e9fafc2c114e079829974e3764db75 从@JoshMc 借来的(谢谢!)并添加了标题功能和更强大的字符转义。见gist.github.com/plbowers/7560ae793613ee839151624182133159【参考方案2】:

jQuery-CSV

这是一个 jQuery 插件,旨在用作将 CSV 解析为 JavaScript 数据的端到端解决方案。它处理RFC 4180 中出现的每一个边缘情况,以及一些弹出的规范缺失的 Excel/Google 电子表格导出(即主要涉及空值)。

例子:

曲目、艺术家、专辑、年份

Dangerous,'Busta Rhymes','When Disaster Strikes',1997

// Calling this
music = $.csv.toArrays(csv)

// Outputs...
[
  ["track", "artist", "album", "year"],
  ["Dangerous", "Busta Rhymes", "When Disaster Strikes", "1997"]
]

console.log(music[1][2]) // Outputs: 'When Disaster Strikes'

更新:

哦,是的,我还应该提到它是完全可配置的。

music = $.csv.toArrays(csv, 
  delimiter: "'", // Sets a custom value delimiter character
  separator: ';', // Sets a custom field separator character
);

更新 2:

它现在也适用于 Node.js 上的 jQuery。因此,您可以选择使用同一个库进行客户端或服务器端解析。

更新 3:

自从 Google 代码关闭后,jquery-csv has been migrated to GitHub。

免责声明:我也是 jQuery-CSV 的作者。

【讨论】:

为什么是 jQuery csv?为什么它依赖于 jQuery?我已经快速浏览了源代码......看起来你没有使用 jQuery @paulslater19 该插件不依赖于 jquery。相反,它遵循通用的 jQuery 开发指南。包含的所有方法都是静态的,并且驻留在它们自己的命名空间下(即 $.csv)。要在没有 jQuery 的情况下使用它们,只需创建一个全局 $ 对象,插件将在初始化期间绑定到该对象。 解决方案代码中的csv参考.csv filename?我对解析 csv 文件的好 JS/JQuery 工具很感兴趣 @bouncingHippo 在示例中,它只是指一个 csv 数据字符串,但该 lib 可用于使用 html5 File API 在浏览器中本地打开 csv 文件。这是它的一个例子jquery-csv.googlecode.com/git/examples/file-handling.html。 鉴于它不依赖于 jQuery,最好去掉全局“$”依赖,让用户传递他们想要的任何对象引用。如果 jQuery 可用,可能会默认使用它。还有其他使用“$”的库,开发团队可能会使用这些库的最少代理。【参考方案3】:

这是一个极其简单的 CSV 解析器,它处理带逗号、换行符和转义双引号的引用字段。没有拆分或正则表达式。它一次扫描输入字符串 1-2 个字符并构建一个数组。

在http://jsfiddle.net/vHKYH/ 进行测试。

function parseCSV(str) 
    var arr = [];
    var quote = false;  // 'true' means we're inside a quoted field

    // Iterate over each character, keep track of current row and column (of the returned array)
    for (var row = 0, col = 0, c = 0; c < str.length; c++) 
        var cc = str[c], nc = str[c+1];        // Current character, next character
        arr[row] = arr[row] || [];             // Create a new row if necessary
        arr[row][col] = arr[row][col] || '';   // Create a new column (start with empty string) if necessary

        // If the current character is a quotation mark, and we're inside a
        // quoted field, and the next character is also a quotation mark,
        // add a quotation mark to the current column and skip the next character
        if (cc == '"' && quote && nc == '"')  arr[row][col] += cc; ++c; continue; 

        // If it's just one quotation mark, begin/end quoted field
        if (cc == '"')  quote = !quote; continue; 

        // If it's a comma and we're not in a quoted field, move on to the next column
        if (cc == ',' && !quote)  ++col; continue; 

        // If it's a newline (CRLF) and we're not in a quoted field, skip the next character
        // and move on to the next row and move to column 0 of that new row
        if (cc == '\r' && nc == '\n' && !quote)  ++row; col = 0; ++c; continue; 

        // If it's a newline (LF or CR) and we're not in a quoted field,
        // move on to the next row and move to column 0 of that new row
        if (cc == '\n' && !quote)  ++row; col = 0; continue; 
        if (cc == '\r' && !quote)  ++row; col = 0; continue; 

        // Otherwise, append the current character to the current column
        arr[row][col] += cc;
    
    return arr;

【讨论】:

这看起来更干净,更直接。我必须解析一个 4mb 的文件,而其他答案在 ie8 中崩溃了,但这可以解决。 这也对我有用。我必须进行一项修改才能正确处理换行:if (cc == '\r' &amp;&amp; nc == '\n' &amp;&amp; !quote) ++row; col = 0; ++c; continue; if (cc == '\n' &amp;&amp; !quote) ++row; col = 0; continue; 另一位用户 (@sorin-postelnicu) 发布了一个伴随函数,将结果转换为字典对象:jsfiddle.net/8t2po6wh。 是的,无论何时需要速度或内存占用很重要,像这样的干净解决方案要优越得多。状态机式的解析更加流畅。 把它变成一个生成器,让你自己处理更大的数据:example【参考方案4】:

我有 an implementation 作为电子表格项目的一部分。

此代码尚未经过彻底测试,但欢迎任何人使用。

正如一些答案所指出的那样,如果您实际上有 DSV 或 TSV 文件,您的实现会简单得多,因为它们不允许在值中使用记录和字段分隔符。另一方面,CSV 实际上可以在字段中包含逗号和换行符,这破坏了大多数正则表达式和基于拆分的方法。

var CSV = 
    parse: function(csv, reviver) 
        reviver = reviver || function(r, c, v)  return v; ;
        var chars = csv.split(''), c = 0, cc = chars.length, start, end, table = [], row;
        while (c < cc) 
            table.push(row = []);
            while (c < cc && '\r' !== chars[c] && '\n' !== chars[c]) 
                start = end = c;
                if ('"' === chars[c])
                    start = end = ++c;
                    while (c < cc) 
                        if ('"' === chars[c]) 
                            if ('"' !== chars[c+1]) 
                                break;
                            
                            else 
                                chars[++c] = ''; // unescape ""
                            
                        
                        end = ++c;
                    
                    if ('"' === chars[c]) 
                        ++c;
                    
                    while (c < cc && '\r' !== chars[c] && '\n' !== chars[c] && ',' !== chars[c]) 
                        ++c;
                    
                 else 
                    while (c < cc && '\r' !== chars[c] && '\n' !== chars[c] && ',' !== chars[c]) 
                        end = ++c;
                    
                
                row.push(reviver(table.length-1, row.length, chars.slice(start, end).join('')));
                if (',' === chars[c]) 
                    ++c;
                
            
            if ('\r' === chars[c]) 
                ++c;
            
            if ('\n' === chars[c]) 
                ++c;
            
        
        return table;
    ,

    stringify: function(table, replacer) 
        replacer = replacer || function(r, c, v)  return v; ;
        var csv = '', c, cc, r, rr = table.length, cell;
        for (r = 0; r < rr; ++r) 
            if (r) 
                csv += '\r\n';
            
            for (c = 0, cc = table[r].length; c < cc; ++c) 
                if (c) 
                    csv += ',';
                
                cell = replacer(r, c, table[r][c]);
                if (/[,\r\n"]/.test(cell)) 
                    cell = '"' + cell.replace(/"/g, '""') + '"';
                
                csv += (cell || 0 === cell) ? cell : '';
            
        
        return csv;
    
;

【讨论】:

这是我最喜欢的答案之一。这是一个真正的解析器,用不多的代码实现。 如果逗号放在行尾,后面应该有一个空单元格。这段代码只是跳到下一行,产生一个undefined 单元格。例如,console.log(CSV.parse("first,last,age\r\njohn,doe,")); 此外,空单元格应解析为空字符串。此代码将它们解析为零,这令人困惑,因为单元格实际上可以包含零:console.log(CSV.parse("0,,2,3")); @skibulk 您的第二条评论不正确(至少在 Chrome 中您的示例可以正常工作)。您的第一条评论是有效的,尽管它很容易修复 - 在 if ('\r' === chars[c]) ... 之前添加以下内容:if (end === c-1) row.push(reviver(table.length-1, row.length, '')); 【参考方案5】:

csvToArray v1.3

一个紧凑(645 字节)但兼容的函数,用于将 CSV 字符串转换为二维数组,符合 RFC4180 标准。

https://code.google.com/archive/p/csv-to-array/downloads

常用用法:jQuery

 $.ajax(
        url: "test.csv",
        dataType: 'text',
        cache: false
 ).done(function(csvAsString)
        csvAsArray=csvAsString.csvToArray();
 );

常用用法:JavaScript

csvAsArray = csvAsString.csvToArray();

覆盖字段分隔符

csvAsArray = csvAsString.csvToArray("|");

覆盖记录分隔符

csvAsArray = csvAsString.csvToArray("", "#");

覆盖跳过标题

csvAsArray = csvAsString.csvToArray("", "", 1);

全部覆盖

csvAsArray = csvAsString.csvToArray("|", "#", 1);

【讨论】:

这听起来很有趣,但我现在找不到代码。可以再发一次吗? 我已经用当前链接更新了主帖。非常感谢。 它在 Google 代码存档中,但可能会更新到新位置?【参考方案6】:

这是我的 PEG(.js) 语法,它在 RFC 4180 上似乎没问题(即它处理 http://en.wikipedia.org/wiki/Comma-separated_values 处的示例):

start
  = [\n\r]* first:line rest:([\n\r]+ data:line  return data; )* [\n\r]*  rest.unshift(first); return rest; 

line
  = first:field rest:("," text:field  return text; )*
    &  return !!first || rest.length;  // ignore blank lines
     rest.unshift(first); return rest; 

field
  = '"' text:char* '"'  return text.join(''); 
  / text:[^\n\r,]*  return text.join(''); 

char
  = '"' '"'  return '"'; 
  / [^"]

在http://jsfiddle.net/knvzk/10 或http://pegjs.majda.cz/online 试用。在https://gist.github.com/3362830下载生成的解析器。

【讨论】:

PEG?对于 III 型语法来说,构建 AST 是不是有点记忆重。它能否处理包含换行符的字段,因为这是“常规语法”解析器中最难涵盖的情况。无论哪种方式,为新颖的方法 +1。 是的,它处理字段内的换行符。 很好...仅此一项,就比我见过的所有实现中的 95% 都要好。如果您想检查完整的 RFC 合规性,请查看此处的测试 (jquery-csv.googlecode.com/git/test/test.html)。 玩得很好。 +1 让我开始使用 PEG。我确实喜欢解析器生成器。 “为什么要在五天内手动编程你可以花五年时间自动化的东西?” -- Terence Parr, ANTLR【参考方案7】:

这是我的简单原生 JavaScript 代码:

let a = 'one,two,"three, but with a comma",four,"five, with ""quotes"" in it.."'
console.log(splitQuotes(a))

function splitQuotes(line) 
  if(line.indexOf('"') < 0) 
    return line.split(',')

  let result = [], cell = '', quote = false;
  for(let i = 0; i < line.length; i++) 
    char = line[i]
    if(char == '"' && line[i+1] == '"') 
      cell += char
      i++
     else if(char == '"') 
      quote = !quote;
     else if(!quote && char == ',') 
      result.push(cell)
      cell = ''
     else 
      cell += char
    
    if ( i == line.length-1 && cell) 
      result.push(cell)
    
  
  return result

【讨论】:

【参考方案8】:

我不知道为什么我不能让Kirtan's example 为我工作。它似乎在空字段或带有尾随逗号的字段上失败......

这个似乎可以同时处理这两个问题。

我没有编写解析器代码,只是对解析器函数进行了包装,以使其适用于文件。查看归因。

    var Strings = 
        /**
         * Wrapped CSV line parser
         * @param s      String delimited CSV string
         * @param sep    Separator override
         * @attribution: http://www.greywyvern.com/?post=258 (comments closed on blog :( )
         */
        parseCSV : function(s,sep) 
            // http://***.com/questions/1155678/javascript-string-newline-character
            var universalNewline = /\r\n|\r|\n/g;
            var a = s.split(universalNewline);
            for(var i in a)
                for (var f = a[i].split(sep = sep || ","), x = f.length - 1, tl; x >= 0; x--) 
                    if (f[x].replace(/"\s+$/, '"').charAt(f[x].length - 1) == '"') 
                        if ((tl = f[x].replace(/^\s+"/, '"')).length > 1 && tl.charAt(0) == '"') 
                            f[x] = f[x].replace(/^\s*"|"\s*$/g, '').replace(/""/g, '"');
                           else if (x) 
                        f.splice(x - 1, 2, [f[x - 1], f[x]].join(sep));
                       else f = f.shift().split(sep).concat(f);
                     else f[x].replace(/""/g, '"');
                   a[i] = f;
        
        return a;
        
    

【讨论】:

【参考方案9】:

正则表达式助你一臂之力!这几行代码根据 RFC 4180 标准处理带有嵌入逗号、引号和换行符的正确引用字段。

function parseCsv(data, fieldSep, newLine) 
    fieldSep = fieldSep || ',';
    newLine = newLine || '\n';
    var nSep = '\x1D';
    var qSep = '\x1E';
    var cSep = '\x1F';
    var nSepRe = new RegExp(nSep, 'g');
    var qSepRe = new RegExp(qSep, 'g');
    var cSepRe = new RegExp(cSep, 'g');
    var fieldRe = new RegExp('(?<=(^|[' + fieldSep + '\\n]))"(|[\\s\\S]+?(?<![^"]"))"(?=($|[' + fieldSep + '\\n]))', 'g');
    var grid = [];
    data.replace(/\r/g, '').replace(/\n+$/, '').replace(fieldRe, function(match, p1, p2) 
        return p2.replace(/\n/g, nSep).replace(/""/g, qSep).replace(/,/g, cSep);
    ).split(/\n/).forEach(function(line) 
        var row = line.split(fieldSep).map(function(cell) 
            return cell.replace(nSepRe, newLine).replace(qSepRe, '"').replace(cSepRe, ',');
        );
        grid.push(row);
    );
    return grid;


const csv = 'A1,B1,C1\n"A ""2""","B, 2","C\n2"';
const separator = ',';      // field separator, default: ','
const newline = ' <br /> '; // newline representation in case a field contains newlines, default: '\n' 
var grid = parseCsv(csv, separator, newline);
// expected: [ [ 'A1', 'B1', 'C1' ], [ 'A "2"', 'B, 2', 'C <br /> 2' ] ]

您不需要像 lex/yacc 这样的解析器生成器。正则表达式能够正确处理 RFC 4180,这要归功于正向后视、负向反向和正向前瞻。

在https://github.com/peterthoeny/parse-csv-js克隆/下载代码

【讨论】:

正则表达式是使用有限状态机实现的,所以实际上需要 FSM。 @HenryHenrinson:不一定。我挑战你找出上面代码的问题。我在生产中使用它。也可以使用正则表达式进行更复杂的解析。您不需要 LL 解析器来创建语法树。这是一篇博客:如何使用正则表达式解析嵌套结构,twiki.org/cgi-bin/view/Blog/BlogEntry201109x3 @HenryHenrinson:哦,是的,傻瓜,我们的协议很激烈 :-)【参考方案10】:

这是另一个解决方案。这使用:

一个粗略的全局正则表达式,用于拆分 CSV 字符串(包括引号和尾随逗号) 细粒度的正则表达式,用于清理周围的引号和尾随逗号 还具有区分字符串、数字和布尔值的类型校正

对于以下输入字符串:

"This is\, a value",Hello,4,-123,3.1415,'This is also\, possible',true

代码输出:

[
  "This is, a value",
  "Hello",
  4,
  -123,
  3.1415,
  "This is also, possible",
  true
]

这是我在可运行代码 sn-p 中的 parseCSVLine() 实现:

function parseCSVLine(text) 
  return text.match( /\s*(\".*?\"|'.*?'|[^,]+)\s*(,|$)/g ).map( function (text) 
    let m;
    if (m = text.match(/^\s*\"(.*?)\"\s*,?$/)) return m[1]; // Double Quoted Text
    if (m = text.match(/^\s*'(.*?)'\s*,?$/)) return m[1]; // Single Quoted Text
    if (m = text.match(/^\s*(true|false)\s*,?$/)) return m[1] === "true"; // Boolean
    if (m = text.match(/^\s*((?:\+|\-)?\d+)\s*,?$/)) return parseInt(m[1]); // Integer Number
    if (m = text.match(/^\s*((?:\+|\-)?\d*\.\d*)\s*,?$/)) return parseFloat(m[1]); // Floating Number
    if (m = text.match(/^\s*(.*?)\s*,?$/)) return m[1]; // Unquoted Text
    return text;
   );


let data = `"This is\, a value",Hello,4,-123,3.1415,'This is also\, possible',true`;
let obj = parseCSVLine(data);
console.log( JSON.stringify( obj, undefined, 2 ) );

【讨论】:

这很整洁!这是 npm 包的一部分吗? 我对第一个正则表达式进行了更改:text.match( /\s*(\".*?\"|'.*?'|[^,]+|)\s*(,|$)/g ) 我必须将最后一个 | 添加到第一个捕获组中以允许 CSV 中的空单元格。 现在我很快意识到这为我创造了另一个极端情况,它在结尾处匹配了一个空字符串,这是多余的。尝试添加负前瞻以在最后不计算空:text.match(/\s*(".*?"|'.*?'|[^,]+|(?!$))\s*(,|$)/g) 这造成了另一个问题,我不能有一个空的最后一个单元格。我可能会回到原来的修复,只过滤掉最后一列中多余的空单元格。【参考方案11】:

只是把它扔在那里.. 我最近遇到了用 Javascript 解析 CSV 列的需求,我选择了我自己的 simple 解决方案。它可以满足我的需求,并且可以帮助其他人。

const csvString = '"Some text, some text",,"",true,false,"more text","more,text, more, text ",true';

const parseCSV = text => 
  const lines = text.split('\n');
  const output = [];

  lines.forEach(line => 
      line = line.trim();

      if (line.length === 0) return;

      const skipIndexes = ;
      const columns = line.split(',');

      output.push(columns.reduce((result, item, index) => 
          if (skipIndexes[index]) return result;

          if (item.startsWith('"') && !item.endsWith('"')) 
              while (!columns[index + 1].endsWith('"')) 
                  index++;
                  item += `,$columns[index]`;
                  skipIndexes[index] = true;
              

              index++;
              skipIndexes[index] = true;
              item += `,$columns[index]`;
          

          result.push(item);
          return result;
      , []));
  );

  return output;
;

console.log(parseCSV(csvString));

【讨论】:

【参考方案12】:

我已经构建了这个 JavaScript 脚本来将字符串中的 CSV 解析为数组对象。我发现将整个 CSV 分解为行、字段并相应地处理它们会更好。我认为这将使您可以轻松更改代码以满足您的需要。

    //
    //
    // CSV to object
    //
    //

    const new_line_char = '\n';
    const field_separator_char = ',';

    function parse_csv(csv_str) 

        var result = [];

        let line_end_index_moved = false;
        let line_start_index = 0;
        let line_end_index = 0;
        let csr_index = 0;
        let cursor_val = csv_str[csr_index];
        let found_new_line_char = get_new_line_char(csv_str);
        let in_quote = false;

        // Handle \r\n
        if (found_new_line_char == '\r\n') 
            csv_str = csv_str.split(found_new_line_char).join(new_line_char);
        
        // Handle the last character is not \n
        if (csv_str[csv_str.length - 1] !== new_line_char) 
            csv_str += new_line_char;
        

        while (csr_index < csv_str.length) 
            if (cursor_val === '"') 
                in_quote = !in_quote;
             else if (cursor_val === new_line_char) 
                if (in_quote === false) 
                    if (line_end_index_moved && (line_start_index <= line_end_index)) 
                        result.push(parse_csv_line(csv_str.substring(line_start_index, line_end_index)));
                        line_start_index = csr_index + 1;
                     // Else: just ignore line_end_index has not moved or line has not been sliced for parsing the line
                 // Else: just ignore because we are in a quote
            
            csr_index++;
            cursor_val = csv_str[csr_index];
            line_end_index = csr_index;
            line_end_index_moved = true;
        

        // Handle \r\n
        if (found_new_line_char == '\r\n') 
            let new_result = [];
            let curr_row;
            for (var i = 0; i < result.length; i++) 
                curr_row = [];
                for (var j = 0; j < result[i].length; j++) 
                    curr_row.push(result[i][j].split(new_line_char).join('\r\n'));
                
                new_result.push(curr_row);
            
            result = new_result;
        
        return result;
    

    function parse_csv_line(csv_line_str) 

        var result = [];

        //let field_end_index_moved = false;
        let field_start_index = 0;
        let field_end_index = 0;
        let csr_index = 0;
        let cursor_val = csv_line_str[csr_index];
        let in_quote = false;

        // Pretend that the last char is the separator_char to complete the loop
        csv_line_str += field_separator_char;

        while (csr_index < csv_line_str.length) 
            if (cursor_val === '"') 
                in_quote = !in_quote;
             else if (cursor_val === field_separator_char) 
                if (in_quote === false) 
                    if (field_start_index <= field_end_index) 
                        result.push(parse_csv_field(csv_line_str.substring(field_start_index, field_end_index)));
                        field_start_index = csr_index + 1;
                     // Else: just ignore field_end_index has not moved or field has not been sliced for parsing the field
                 // Else: just ignore because we are in quote
            
            csr_index++;
            cursor_val = csv_line_str[csr_index];
            field_end_index = csr_index;
            field_end_index_moved = true;
        
        return result;
    

    function parse_csv_field(csv_field_str) 
        with_quote = (csv_field_str[0] === '"');

        if (with_quote) 
            csv_field_str = csv_field_str.substring(1, csv_field_str.length - 1); // remove the start and end quotes
            csv_field_str = csv_field_str.split('""').join('"'); // handle double quotes
        
        return csv_field_str;
    

    // Initial method: check the first newline character only
    function get_new_line_char(csv_str) 
        if (csv_str.indexOf('\r\n') > -1) 
            return '\r\n';
         else 
            return '\n'
        
    

【讨论】:

【参考方案13】:

只需使用.split(','):

var str = "How are you doing today?";
var n = str.split(" ");

【讨论】:

为什么这是一个糟糕的答案?它是原生的,将字符串内容放入可用的数组中...... 很多的原因。首先,它不会删除分隔值上的双引号。不处理行拆分。不转义用于转义分隔值中使用的双引号的双双引号。不允许空值。等等,等等... CSV 格式的灵活性使其非常易于使用但难以解析。我不会对此投反对票,只是因为我不会对竞争性答案投反对票。 遇到包含换行符的值怎么办?一个简单的拆分函数会错误地将其解释为条目的结尾,而不是像应有的那样跳过它。解析 CSV 比仅提供 2 个拆分例程(一个用于换行符,一个用于分隔符)复杂得多。 (cont) 同样拆分空值 (a,null,,value) 不返回任何内容,而它应该返回一个空字符串。不要误会我的意思,如果您 100% 肯定传入的数据不会破坏解析器,那么拆分是一个好的开始,但是创建一个可以处理任何符合 RFC 4801 的数据的强大解析器要复杂得多。跨度> 埃文,我认为你的 JavaScript 库很棒。但这是另一种观点 - 我很欣赏这个答案,因为我只是以一种非常可预测的方式存储一系列数字。对我来说,尽可能保证跨浏览器的 Javascript 兼容性和可维护性比包含一个大型(尽管编写良好且经过良好测试)库更重要。不同的需求需要不同的方法。如果我需要真正的 CSV 功能,我一定会承诺使用您的库! :-)

以上是关于用于解析 CSV 数据的示例 JavaScript 代码的主要内容,如果未能解决你的问题,请参考以下文章

在 Fusioncharts 和纯 JAVASCRIPT 示例中显示 JSON、XML、CSV 数据

如何在javascript中解析和格式化不规则CSV中的字符串?

解析一个非常大的 CSV 数据集

Python CSV 解析,转义引号字符

如何从字符向量中解析 CSV 数据以提取数据框?

用于解析 CSV 的正则表达式