解析 CSV 数据的 JavaScript 代码示例

IT技术 javascript csv
2021-01-15 02:07:13

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

6个回答

您可以使用此博客条目中提到CSVToArray()函数。

<script type="text/javascript">
    // ref: http://stackoverflow.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>
对于任何寻找上述方法的简化版本的人,应用上述正则表达式修复:gist.github.com/Jezternz/c8e9fafc2c114e079829974e3764db75
2021-03-19 02:07:13
它给undefined空字段引用示例:CSVToArray("4,,6")给了我[["4","","6"]],但CSVToArray("4,\"\",6")给了我[["4",undefined,"6"]]
2021-03-23 02:07:13
正则表达式中有一个错误:"([^\"\\"应该是"([^\\". 否则,未加引号的值中任何地方的双引号将过早结束它。发现这很难...
2021-03-27 02:07:13
从@JoshMc 借来(谢谢!)并添加了标头功能和更强大的字符转义。gist.github.com/plbowers/7560ae793613ee839151624182133159
2021-03-28 02:07:13
我在 Firefox 中遇到了这个问题,脚本变得没有响应。不过好像只影响了少数用户,所以找不到原因
2021-04-05 02:07:13

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 Code 关闭以来,jquery-csv 已迁移到 GitHub

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

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

这是一个非常简单的 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;
}
把它变成一个生成器,你就得到了一种处理更大数据的方法:例子
2021-03-19 02:07:13
这也对我有用。我不得不做一个修改,但允许正确处理换行符:if (cc == '\r' && nc == '\n' && !quote) { ++row; col = 0; ++c; continue; } if (cc == '\n' && !quote) { ++row; col = 0; continue; }
2021-03-22 02:07:13
另一位用户 (@sorin-postelnicu) 帮助发布了一个配套函数,将结果转换为字典对象:jsfiddle.net/8t2po6wh
2021-03-30 02:07:13
是的,任何时候都需要速度或内存占用很重要,像这样的干净解决方案要优越得多。状态机式的解析要平滑得多。
2021-03-30 02:07:13
这看起来更干净,更直接。我不得不解析一个 4mb 的文件,而其他答案在 ie8 中崩溃了,但这成功了。
2021-04-03 02:07:13

我有一个实现作为电子表格项目的一部分。

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

但是,正如某些答案所指出的那样,如果您确实拥有DSVTSV文件,则您的实现可能会简单得多,因为它们不允许在值中使用记录和字段分隔符。另一方面,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;
    }
};
此外,空单元格应解析为空字符串。此代码将它们解析为零,这令人困惑,因为单元格实际上可以包含零:console.log(CSV.parse("0,,2,3"));
2021-03-17 02:07:13
@skibulk 您的第二条评论不正确(至少在 Chrome 中适用于您的示例)。虽然您的第一条评论是有效的,但它很容易修复 - 在之前添加以下内容if ('\r' === chars[c]) { ... }if (end === c-1) { row.push(reviver(table.length-1, row.length, '')); }
2021-03-21 02:07:13
如果逗号放在行尾,则后面应有一个空单元格。这段代码只是跳到下一行,产生一个undefined单元格。例如,console.log(CSV.parse("first,last,age\r\njohn,doe,"));
2021-03-25 02:07:13
这是我最喜欢的答案之一。这是一个真正的解析器,用不多的代码实现。
2021-04-02 02:07:13

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 代码档案中,但也许更新到新位置?
2021-03-12 02:07:13
这听起来很有趣,但我现在找不到代码。你能再发一次吗?
2021-03-22 02:07:13
我已经用当前链接更新了主要帖子。非常感谢。
2021-03-22 02:07:13