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


当前回答

jQuery-CSV

它是一个jQuery插件,设计用于将CSV解析为JavaScript数据的端到端解决方案。它处理RFC 4180中提出的每一个边缘情况,以及一些Excel/谷歌电子表格导出中弹出的情况(即,大多数涉及空值),这些都是规范所缺少的。

例子:

轨道,艺术家,专辑, 危险,“巴斯塔韵脚”,“当灾难袭来”,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:

自从谷歌代码关闭后,jquery-csv已经迁移到GitHub。

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

其他回答

下面是我的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下载生成的解析器。

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

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

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

一个粗略的全局正则表达式,用于分割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,
  null
]

下面是我在一个可运行的代码片段中实现的parseCSVLine():

function parseCSVLine(text) { return text.match( /\s*(\"[^"]*\"|'[^']*'|[^,]*)\s*(,|$)/g ).map( function (text) { let m; if (m = text.match(/^\s*,?$/)) return null; // null value 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 ) );

csvToArray v1.3

一个紧凑(645字节),但兼容的函数,将CSV字符串转换为2D数组,符合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);

我已经构造了这个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'
        }
    }