Mã Javascript để phân tích dữ liệu CSV


215

Có ai có ý tưởng về nơi tôi có thể tìm thấy một số mã javascript để phân tích dữ liệu CSV không?


3
Hãy xem câu trả lời này tại đây, nó có câu trả lời hay: stackoverflow.com/questions/8493195/iêu
Dobes Vandermeer

14
Hầu hết các câu trả lời dưới đây chỉ sai, ngoài câu trả lời của Andy. Bất kỳ câu trả lời nào sử dụng khớp mẫu hoặc chia tách đều bị thất bại - chúng sẽ không hỗ trợ các chuỗi thoát. Đối với điều đó, bạn cần một máy trạng thái hữu hạn.
greg.kindel

3
Phân tích tệp CSV cục bộ bằng JavaScript và Papa Parse: joyofdata.de/blog/ triệt
Raffael

4
Papa Parse là một tùy chọn khác với rất nhiều tính năng (đa luồng, hỗ trợ hàng tiêu đề, tự động phát hiện dấu phân cách và hơn thế nữa)
Hinrich

1
Một phiếu bầu khác cho PapaPude, tôi đang sử dụng nó với AngularJS và nó hoạt động rất tốt.
Dmitry Buslaev

Câu trả lời:


257

Bạn có thể sử dụng hàm CSVToArray () được đề cập trong mục blog này.

<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>

1
Điều này có thể xử lý dấu phẩy, dấu ngoặc kép và dấu ngắt dòng, ví dụ: var csv = 'id, value \ n1, James \ n02, "Jimmy Smith, Esq." \ N003, "James" "Jimmy" "Smith, III" \ n0004, "James \ nSmith \ nWuz Tại đây" 'var mảng = CSVToArray (csv, ",");
nguyên mẫu

4
Nó cung cấp undefinedcho các trường trống được trích dẫn . Ví dụ: CSVToArray("4,,6")cho tôi [["4","","6"]], nhưng CSVToArray("4,\"\",6")cho tôi [["4",undefined,"6"]].
Pang

3
Tôi đã có vấn đề với điều này trong firefox và kịch bản đã trở nên không phản hồi. Nó dường như chỉ ảnh hưởng đến một vài người dùng, vì vậy không thể tìm ra nguyên nhân
JDandChips 18/03/13

8
Có một lỗi trong regex: "([^\"\\"nên "([^\\". Nếu không, một trích dẫn kép ở bất cứ đâu trong một giá trị không được trích dẫn sẽ kết thúc sớm. Các mặt hàng này một cách khó khăn ...
Walter Tross

5
Đối với bất kỳ ai đang tìm kiếm phiên bản rút gọn của phương pháp trên, với bản sửa lỗi regex được mô tả ở trên được áp dụng: gist.github.com/Jezternz/c8e9fafc2c114e079829974e3764db75
Josh Mc

147

jQuery-CSV

Đây là một plugin jquery được thiết kế để hoạt động như một giải pháp đầu cuối để phân tích CSV thành dữ liệu Javascript. Nó xử lý mọi trường hợp cạnh đơn được trình bày trong RFC 4180 , cũng như một số trường hợp xuất hiện cho xuất khẩu Excel / Google Spreadsheed (nghĩa là chủ yếu liên quan đến các giá trị null) mà thông số kỹ thuật bị thiếu.

Thí dụ:

ca khúc, nghệ sĩ, album, năm

Nguy hiểm, 'Busta Rhymes', 'Khi thảm họa xảy ra', 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'

Cập nhật:

Ồ vâng, tôi cũng có lẽ nên đề cập rằng nó hoàn toàn có thể cấu hình.

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

Cập nhật 2:

Bây giờ nó cũng hoạt động với jQuery trên Node.js. Vì vậy, bạn có tùy chọn thực hiện phân tích cú pháp phía máy khách hoặc phía máy chủ với cùng lib.

Cập nhật 3:

Kể từ khi Google Code ngừng hoạt động, jquery-csv đã được chuyển sang GitHub .

Tuyên bố miễn trừ trách nhiệm: Tôi cũng là tác giả của jQuery-CSV.


29
Tại sao lại là jQuery csv? Tại sao nó phụ thuộc vào jQuery? Tôi đã quét nhanh qua nguồn ... có vẻ như bạn đang sử dụng jQuery
paulslater19

17
@ paulslater19 Plugin không phụ thuộc vào jquery. Thay vào đó, nó tuân theo các nguyên tắc phát triển jQuery phổ biến. Tất cả các phương thức được bao gồm là tĩnh và nằm trong không gian tên riêng của chúng (ví dụ $ .csv). Để sử dụng chúng mà không cần jQuery, chỉ cần tạo một đối tượng $ toàn cầu mà plugin sẽ liên kết trong quá trình khởi tạo.
Evan Plaice

2
csvtrong mã giải pháp đề cập đến .csv filename? Tôi quan tâm đến một công cụ JS / JQuery tốt để phân tích tệp csv
bouncingHippo

1
@bouncingHippo Trong ví dụ, nó chỉ đề cập đến một chuỗi dữ liệu csv nhưng lib có thể được sử dụng để mở tệp csv cục bộ trong trình duyệt bằng API tệp HTML5. Đây là một ví dụ về nó trong hành động jquery-csv.googlecode.com/git/examples/file-handling.html .
Evan Plaice

1
Vì nó không phụ thuộc vào jQuery, sẽ tốt hơn nếu loại bỏ sự phụ thuộc "$" toàn cầu và cho phép người dùng vượt qua bất kỳ tham chiếu đối tượng nào họ muốn. Có lẽ mặc định với jQuery nếu nó có sẵn. Có những thư viện khác sử dụng "$" và nó có thể được sử dụng bởi các nhóm phát triển với các proxy tối thiểu của các thư viện đó.
RobG

40

Tôi có một triển khai như là một phần của dự án bảng tính.

Mã này chưa được kiểm tra kỹ lưỡng, nhưng bất kỳ ai cũng được hoan nghênh sử dụng nó.

Như một số câu trả lời đã lưu ý, việc triển khai của bạn có thể đơn giản hơn nhiều nếu bạn thực sự có tệp DSV hoặc TSV , vì chúng không cho phép sử dụng các bản ghi và dấu tách trường trong các giá trị. Mặt khác, CSV thực sự có thể có dấu phẩy và dòng mới bên trong một trường, phá vỡ hầu hết các cách tiếp cận dựa trên regex và split.

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;
}
};

9
Đây là một trong những câu trả lời yêu thích của tôi. Đó là một trình phân tích cú pháp thực sự được triển khai trong không nhiều mã.
Trevor Dixon

1
Nếu dấu phẩy được đặt ở cuối dòng, một ô trống sẽ theo sau nó. Mã này chỉ bỏ qua dòng tiếp theo, dẫn đến một undefinedô. Ví dụ:console.log(CSV.parse("first,last,age\r\njohn,doe,"));
skibulk

Ngoài ra, các ô trống nên phân tích thành các chuỗi trống. Mã này phân tích chúng thành các số không, điều này gây nhầm lẫn vì các ô thực sự có thể chứa các số không:console.log(CSV.parse("0,,2,3"));
skibulk

@skibulk Nhận xét thứ hai của bạn không chính xác (ít nhất là trong Chrome hoạt động tốt với ví dụ của bạn). Nhận xét đầu tiên của bạn là hợp lệ, mặc dù nó dễ dàng được sửa chữa - thêm phần sau ngay trước if ('\r' === chars[c]) { ... }:if (end === c-1) { row.push(reviver(table.length-1, row.length, '')); }
coderforlife 7/11/2016

35

Đây là một trình phân tích cú pháp CSV cực kỳ đơn giản để xử lý các trường được trích dẫn bằng dấu phẩy, dòng mới và thoát dấu ngoặc kép. Không có chia tách hoặc RegEx. Nó quét chuỗi đầu vào 1-2 ký tự một lần và xây dựng một mảng.

Kiểm tra nó tại 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;
}

Nó đơn giản và nó hoạt động với tôi, điều duy nhất tôi đã thay đổi là thêm một trim () vào giá trị :)
JustEngland

3
Điều này có vẻ sạch hơn và thẳng hơn về phía trước. Tôi đã phải phân tích một tệp 4mb và các câu trả lời khác đã bị lỗi trong tôi trong 8, nhưng điều này đã quản lý nó.
Charles Clayton

3
Điều này cũng làm việc cho tôi. Tôi đã phải thực hiện một sửa đổi mặc dù để cho phép xử lý đúng các nguồn cấp dữ liệu:if (cc == '\r' && nc == '\n' && !quote) { ++row; col = 0; ++c; continue; } if (cc == '\n' && !quote) { ++row; col = 0; continue; }
user655063

1
Một người dùng khác (@ sorin-postelnicu) đã xuất bản một cách hữu ích một chức năng đồng hành để biến kết quả thành một đối tượng từ điển: jsfiddle.net/8t2po6wh .
Trevor Dixon

1
Vâng, bất cứ lúc nào tốc độ là cần thiết hoặc dấu chân bộ nhớ là một vấn đề, một giải pháp sạch như thế này là vượt trội hơn nhiều. Phân tích cú pháp máy esque mượt mà hơn rất nhiều.
Tatarize

14

Đây là ngữ pháp PEG (.js) của tôi có vẻ ổn ở RFC 4180 (tức là nó xử lý các ví dụ tại 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 '"'; }
  / [^"]

Dùng thử tại http://jsfiddle.net/knvzk/10 hoặc http://pegjs.majda.cz/online . Tải xuống trình phân tích cú pháp được tạo tại https://gist.github.com/3362830 .


2
CỌC? Không xây dựng AST một chút bộ nhớ nặng cho ngữ pháp Loại III. Nó có thể xử lý các trường có chứa ký tự dòng mới không vì đó là trường hợp khó khăn nhất trong trình phân tích cú pháp 'ngữ pháp thông thường'. Dù bằng cách nào, +1 cho một cách tiếp cận tiểu thuyết.
Evan Plaice

1
Vâng, nó xử lý dòng mới trong một lĩnh vực.
Trevor Dixon

2
Thật tuyệt ... Chỉ với điều đó, nó tốt hơn 95% so với tất cả các triển khai tôi từng thấy. Nếu bạn muốn kiểm tra sự tuân thủ RFC đầy đủ, hãy xem các thử nghiệm tại đây ( jquery-csv.googlecode.com/git/test/test.html ).
Evan Plaice

6
Chơi tốt +1 để bật tôi lên PEG. Tôi thích trình phân tích cú pháp. "Tại sao lập trình bằng tay trong năm ngày những gì bạn có thể dành năm năm cuộc đời của bạn tự động hóa?" - Terence Parr, ANTLR
Subfuzion

14

csvToArray v1.3

Một chức năng nhỏ gọn (645 byte) nhưng tuân thủ để chuyển đổi chuỗi CSV thành mảng 2D, tuân thủ tiêu chuẩn RFC4180.

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

Cách sử dụng phổ biến: jQuery

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

Sử dụng phổ biến: Javascript

csvAsArray = csvAsString.csvToArray();

Ghi đè trường phân cách

csvAsArray = csvAsString.csvToArray("|");

Ghi đè phân tách bản ghi

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

Ghi đè Bỏ qua tiêu đề

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

Ghi đè tất cả

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

Điều này nghe có vẻ thú vị nhưng tôi không thể tìm thấy mã bây giờ. Bạn có thể gửi nó một lần nữa?
Sam Watkins

1
Tôi đã cập nhật bài viết chính với một liên kết hiện tại. Cảm ơn nhiều.
dt192

3

Tôi không chắc tại sao tôi không thể kirtans cũ. để làm việc cho tôi Nó dường như thất bại trên các trường trống hoặc có thể các trường có dấu phẩy ...

Điều này dường như để xử lý cả hai.

Tôi đã không viết mã trình phân tích cú pháp, chỉ là một trình bao bọc xung quanh chức năng của trình phân tích cú pháp để làm cho công việc này cho một tệp. xem ghi công

    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://stackoverflow.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;
        }
    }

1

Biểu hiện thường xuyên để giải cứu! Một vài dòng mã này xử lý các trường được trích dẫn chính xác với dấu phẩy, dấu ngoặc kép và dòng mới được nhúng dựa trên tiêu chuẩn 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' ] ]

Bạn không cần một trình tạo trình phân tích cú pháp như lex / yacc. Biểu thức chính quy xử lý RFC 4180 đúng cách nhờ vào cái nhìn tích cực, cái nhìn tiêu cực và cái nhìn tích cực.

Sao chép / tải xuống mã tại https://github.com/peterthoeny/parse-csv-js


Regexps được triển khai bằng các máy trạng thái hữu hạn, trên thực tế, bạn cần FSM.
Henry Henrinson

@HenryHenrinson: Không nhất thiết. Tôi thách bạn tìm một vấn đề với đoạn mã trên. Tôi sử dụng nó trong sản xuất. Cũng có thể thực hiện phân tích cú pháp phức tạp hơn với các biểu thức thông thường. Bạn không cần một trình phân tích cú pháp LL để tạo cây cú pháp. Đây là một blog: Cách sử dụng biểu thức chính quy để phân tích cấu trúc lồng nhau, twiki.org/cgi-bin/view/Blog/BlogEntry201109x3
Peter Thoeny

@HenryHenrinson: Ồ, vâng, giả tôi, chúng tôi đang có thỏa thuận bạo lực :-)
Peter Thoeny

-1

Tôi đã xây dựng tập lệnh javascript này để phân tích CSV trong chuỗi thành đối tượng mảng. Tôi thấy tốt hơn khi chia toàn bộ CSV thành các dòng, trường và xử lý chúng cho phù hợp. Tôi nghĩ rằng nó sẽ giúp bạn dễ dàng thay đổi mã cho phù hợp với nhu cầu của bạn.

Tôi hy vọng nó sẽ giúp bạn. Cảm ơn.

    //
    //
    // 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 last char 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 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'
        }
    }

-3

Tại sao không chỉ sử dụng .split (',')?

http://www.w3schools.com/jsref/jsref_split.asp

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

2
Tại sao đây là một câu trả lời xấu? Nó là nguồn gốc, đặt nội dung chuỗi thành mảng khả thi ...
Micah

20
Rất nhiều lý do. Đầu tiên, nó không xóa dấu ngoặc kép trên các giá trị được phân tách. Không xử lý tách dòng. Không thoát dấu ngoặc kép được sử dụng để thoát dấu ngoặc kép được sử dụng trong các giá trị được phân tách. Không cho phép các giá trị trống. vv, vv ... Tính linh hoạt của định dạng CSV làm cho nó rất dễ sử dụng nhưng khó phân tích. Tôi sẽ không đánh giá thấp điều này nhưng chỉ vì tôi không đánh giá thấp câu trả lời cạnh tranh.
Evan Plaice

1
Còn khi bạn gặp một giá trị có chứa char dòng mới thì sao? Một hàm phân tách đơn giản sẽ diễn giải không chính xác nó là phần cuối của một mục thay vì bỏ qua nó như bình thường. Phân tích cú pháp CSV phức tạp hơn nhiều so với việc chỉ cung cấp 2 thói quen phân tách (một cho dòng mới, một cho phân cách).
Evan Plaice

2
(tiếp) Cũng phân chia trên các giá trị null (a, null ,, giá trị) không trả về gì trong khi nó sẽ trả về một chuỗi rỗng. Đừng hiểu sai ý tôi, phân chia là một khởi đầu tốt nếu bạn tích cực 100% rằng dữ liệu đến sẽ không phá vỡ trình phân tích cú pháp nhưng việc tạo một trình phân tích cú pháp mạnh mẽ có thể xử lý bất kỳ dữ liệu nào tuân thủ RFC 4801 thì phức tạp hơn đáng kể.
Evan Plaice

8
Evan, tôi nghĩ rằng thư viện javascript của bạn là tuyệt vời. Nhưng đây là một góc nhìn khác - tôi đánh giá cao câu trả lời này, vì tôi chỉ đơn giản là lưu trữ một loạt các con số theo một cách rất dễ đoán. Điều quan trọng đối với tôi là có được khả năng tương thích và bảo trì Javascript trên trình duyệt được bảo đảm càng xa trong tương lai càng tốt, bao gồm cả một thư viện lớn (mặc dù được viết tốt và được kiểm tra tốt). Nhu cầu khác nhau đòi hỏi cách tiếp cận khác nhau. Nếu tôi cần nguồn CSV thực sự, tôi sẽ HOÀN TOÀN cam kết sử dụng thư viện của bạn! :-)
psychboom
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.