Javascript-Code zum Parsen von CSV-Daten

215

Hat jemand eine Idee, wo ich Javascript-Code zum Parsen von CSV-Daten finden könnte?

Pierre-Gilles Levallois
quelle
3
Schauen Sie sich diese Antwort hier an, sie hat gute Antworten: stackoverflow.com/questions/8493195/…
Vandermeer
14
Die meisten der folgenden Antworten sind einfach falsch, abgesehen von der von Andy. Jede Antwort, die Pattern Matching oder Splits verwendet, ist zum Scheitern verurteilt - sie unterstützen keine Escape-Sequenzen. Dafür benötigen Sie eine Finite-State-Maschine.
Greg.kindel
3
Parsen einer lokalen CSV-Datei mit JavaScript und Papa Parse: joyofdata.de/blog/…
Raffael
4
Papa Parse ist eine weitere Option mit vielen Funktionen (Multithreading, Unterstützung für Header-Zeilen, Trennzeichen für die automatische Erkennung und mehr)
Hinrich,
1
Eine weitere Abstimmung für PapaParse, ich benutze es mit AngularJS und es funktioniert großartig.
Dmitry Buslaev

Antworten:

257

Sie können die in diesem Blogeintrag erwähnte Funktion CSVToArray () verwenden .

<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>
Kirtan
quelle
1
Dies kann eingebettete Kommas, Anführungszeichen und Zeilenumbrüche verarbeiten, z. B.: Var csv = 'id, value \ n1, James \ n02, "Jimmy Smith, Esq." \ N003, "James" "Jimmy" "Smith, III" \ n0004, "James \ nSmith \ nWuz Here" 'var array = CSVToArray (csv, ",");
Prototyp
4
Es gibt undefinedfür leere Felder , die in Anführungszeichen gesetzt werden . Beispiel: CSVToArray("4,,6")gibt mir [["4","","6"]], CSVToArray("4,\"\",6")gibt mir aber [["4",undefined,"6"]].
Pang
3
Ich hatte Probleme damit in Firefox und das Skript reagiert nicht mehr. Es schien jedoch nur wenige Benutzer zu betreffen, konnte also die Ursache nicht finden
JDandChips
8
Es gibt einen Fehler in der Regex: "([^\"\\"sollte sein "([^\\". Andernfalls wird ein doppeltes Anführungszeichen an einer beliebigen Stelle in einem nicht zitierten Wert vorzeitig beendet. Fand das auf die harte Tour ...
Walter Tross
5
Für alle, die nach einer reduzierten Version der oben genannten Methode suchen, gilt der oben beschriebene Regex-Fix: gist.github.com/Jezternz/c8e9fafc2c114e079829974e3764db75
Josh Mc
147

jQuery-CSV

Es ist ein JQuery-Plugin, das als End-to-End-Lösung zum Parsen von CSV in Javascript-Daten entwickelt wurde. Es behandelt jeden einzelnen Randfall , der in RFC 4180 dargestellt wird , sowie einige Fälle , die für Excel / Google Spreadsheed-Exporte (dh meistens mit Nullwerten) angezeigt werden, bei denen die Spezifikation fehlt.

Beispiel:

Track, Künstler, Album, Jahr

Gefährlich, "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'

Aktualisieren:

Oh ja, ich sollte wahrscheinlich auch erwähnen, dass es vollständig konfigurierbar ist.

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

Update 2:

Es funktioniert jetzt auch mit jQuery auf Node.js. Sie haben also die Möglichkeit, entweder clientseitig oder serverseitig mit derselben Bibliothek zu analysieren.

Update 3:

Seit dem Herunterfahren von Google Code wurde jquery-csv auf GitHub migriert .

Haftungsausschluss: Ich bin auch Autor von jQuery-CSV.

Evan Scholle
quelle
29
Warum ist es jQuery csv? Warum hängt es von jQuery ab? Ich habe einen kurzen Scan durch die Quelle gemacht ... es sieht nicht so aus, als würden Sie jQuery verwenden
paulslater19
17
@ paulslater19 Das Plugin hängt nicht von jquery ab. Es folgt vielmehr den allgemeinen Entwicklungsrichtlinien für jQuery. Alle enthaltenen Methoden sind statisch und befinden sich unter ihrem eigenen Namespace (dh $ .csv). Um sie ohne jQuery zu verwenden, erstellen Sie einfach ein globales $ -Objekt, an das das Plugin während der Initialisierung gebunden wird.
Evan Plaice
2
Ist csvim Lösungscode auf die .csv filename? Ich bin an einem guten JS / JQuery-Tool interessiert, um eine CSV-Datei zu analysieren
BouncingHippo
1
@bouncingHippo Im Beispiel bezieht es sich nur auf eine Zeichenfolge von CSV-Daten, aber die Bibliothek kann verwendet werden, um CSV-Dateien lokal im Browser mithilfe der HTML5-Datei-API zu öffnen. Hier ist ein Beispiel dafür in Aktion jquery-csv.googlecode.com/git/examples/file-handling.html .
Evan Plaice
1
Da es nicht von jQuery abhängig ist, ist es besser, die globale "$" - Abhängigkeit zu entfernen und den Benutzern zu erlauben, jede gewünschte Objektreferenz zu übergeben. Möglicherweise standardmäßig jQuery, wenn es verfügbar ist. Es gibt andere Bibliotheken, die "$" verwenden und möglicherweise von Entwicklungsteams mit minimalen Proxys dieser Bibliotheken verwendet werden.
RobG
40

Ich habe eine Implementierung als Teil eines Tabellenkalkulationsprojekts.

Dieser Code wurde noch nicht gründlich getestet, kann aber von jedem verwendet werden.

Wie einige der Antworten jedoch vermerkten, kann Ihre Implementierung viel einfacher sein, wenn Sie tatsächlich über eine DSV- oder TSV- Datei verfügen , da die Verwendung der Datensatz- und Feldtrennzeichen in den Werten nicht zulässig ist. CSV hingegen kann tatsächlich Kommas und Zeilenumbrüche in einem Feld enthalten, wodurch die meisten Regex- und Split-basierten Ansätze gebrochen werden.

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;
}
};
Andy VanWagoner
quelle
9
Dies ist eine meiner Lieblingsantworten. Es ist ein echter Parser, der in nicht viel Code implementiert ist.
Trevor Dixon
1
Wenn am Ende einer Zeile ein Komma steht, sollte eine leere Zelle folgen. Dieser Code springt einfach zur nächsten Zeile, was zu einer undefinedZelle führt. Zum Beispielconsole.log(CSV.parse("first,last,age\r\njohn,doe,"));
Skibulk
Außerdem sollten leere Zellen in leere Zeichenfolgen analysiert werden. Dieser Code analysiert sie in Nullen, was verwirrend ist, da Zellen tatsächlich Nullen enthalten können:console.log(CSV.parse("0,,2,3"));
Skibulk
@skibulk Dein zweiter Kommentar ist falsch (zumindest in Chrome funktioniert er gut mit deinem Beispiel). Ihr erster Kommentar ist jedoch gültig, obwohl er leicht if ('\r' === chars[c]) { ... }if (end === c-1) { row.push(reviver(table.length-1, row.length, '')); }
coderforlife
35

Hier ist ein extrem einfacher CSV-Parser, der Felder in Anführungszeichen mit Kommas, neuen Zeilen und doppelten Anführungszeichen behandelt. Es gibt keine Aufteilung oder RegEx. Es scannt die Eingabezeichenfolge mit jeweils 1-2 Zeichen und erstellt ein Array.

Testen Sie es unter 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;
}
Trevor Dixon
quelle
Es ist einfach und funktioniert für mich. Das einzige, was ich geändert habe, war das Hinzufügen eines trim () zum Wert :)
JustEngland
3
Dies scheint sauberer und direkter zu sein. Ich musste eine 4-MB-Datei analysieren und die anderen Antworten stürzten in ie8 auf mich ab, aber das schaffte es.
Charles Clayton
3
Das hat auch bei mir funktioniert. Ich musste jedoch eine Änderung vornehmen, um die ordnungsgemäße Behandlung von if (cc == '\r' && nc == '\n' && !quote) { ++row; col = 0; ++c; continue; } if (cc == '\n' && !quote) { ++row; col = 0; continue; }
Zeilenvorschüben
1
Ein anderer Benutzer (@ sorin-postelnicu) hat eine Begleitfunktion veröffentlicht, um das Ergebnis in ein Wörterbuchobjekt umzuwandeln : jsfiddle.net/8t2po6wh .
Trevor Dixon
1
Ja, wann immer Geschwindigkeit benötigt wird oder Speicherplatzabdrücke wichtig sind, ist eine saubere Lösung wie diese weit überlegen. State Machine-esque Parsing ist so viel reibungsloser.
Tatarize
14

Hier ist meine PEG (.js) Grammatik, die bei RFC 4180 in Ordnung zu sein scheint (dh sie behandelt die Beispiele unter 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 '"'; }
  / [^"]

Probieren Sie es unter http://jsfiddle.net/knvzk/10 oder http://pegjs.majda.cz/online aus . Laden Sie den generierten Parser unter https://gist.github.com/3362830 herunter .

Trevor Dixon
quelle
2
PEG? Ist das Erstellen eines AST nicht ein wenig speicherlastig für eine Typ-III-Grammatik? Kann es Felder verarbeiten, die Zeilenumbrüche enthalten, da dies der schwierigste Fall ist, der in einem Parser für normale Grammatik behandelt werden kann? In beiden Fällen +1 für einen neuartigen Ansatz.
Evan Plaice
1
Ja, es behandelt Zeilenumbrüche innerhalb eines Feldes.
Trevor Dixon
2
Schön ... Allein damit ist es besser als 95% aller Implementierungen, die ich je gesehen habe. Wenn Sie die vollständige RFC-Konformität überprüfen möchten, sehen Sie sich die Tests hier an ( jquery-csv.googlecode.com/git/test/test.html ).
Evan Plaice
6
Gut gespielt. +1 für das Einschalten von PEG. Ich liebe Parser-Generatoren. "Warum in fünf Tagen von Hand programmieren, was Sie fünf Jahre Ihres Lebens damit verbringen können, zu automatisieren?" - Terence Parr, ANTLR
Subfuzion
14

csvToArray v1.3

Eine kompakte (645 Byte), aber kompatible Funktion zum Konvertieren einer CSV-Zeichenfolge in ein 2D-Array gemäß dem RFC4180-Standard.

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

Allgemeine Verwendung: jQuery

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

Allgemeine Verwendung: Javascript

csvAsArray = csvAsString.csvToArray();

Feldtrennzeichen überschreiben

csvAsArray = csvAsString.csvToArray("|");

Datensatztrennzeichen überschreiben

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

Skip Header überschreiben

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

Alle überschreiben

csvAsArray = csvAsString.csvToArray("|", "#", 1);
dt192
quelle
Das klingt interessant, aber ich kann den Code jetzt nicht finden. Kannst du es nochmal posten?
Sam Watkins
1
Ich habe den Hauptbeitrag mit einem aktuellen Link aktualisiert. Danke vielmals.
dt192
3

Ich bin mir nicht sicher, warum ich nicht kirtans ex konnte. für mich arbeiten. Es schien auf leeren Feldern oder vielleicht auf Feldern mit nachgestellten Kommas zu versagen ...

Dieser scheint mit beiden fertig zu werden.

Ich habe den Parser-Code nicht geschrieben, sondern nur einen Wrapper um die Parser-Funktion, damit dies für eine Datei funktioniert. siehe Namensnennung

    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;
        }
    }
Shanimal
quelle
1

Regelmäßige Ausdrücke zur Rettung! Diese wenigen Codezeilen verarbeiten korrekt in Anführungszeichen gesetzte Felder mit eingebetteten Kommas, Anführungszeichen und Zeilenumbrüchen basierend auf dem RFC 4180-Standard.

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

Sie benötigen keinen Parser-Generator wie lex / yacc. Der reguläre Ausdruck behandelt RFC 4180 dank positivem Lookbehind, negativem Lookbehind und positivem Lookahead ordnungsgemäß.

Klonen / Herunterladen von Code unter https://github.com/peterthoeny/parse-csv-js

Peter Thoeny
quelle
Regexps werden mithilfe von Finite-State-Maschinen implementiert, sodass Sie tatsächlich FSM benötigen.
Henry Henrinson
@ HenryHenrinson: Nicht unbedingt. Ich fordere Sie auf, ein Problem mit dem obigen Code zu finden. Ich benutze es in der Produktion. Es ist auch möglich, komplexere Analysen mit regulären Ausdrücken durchzuführen. Sie benötigen keinen LL-Parser, um einen Syntaxbaum zu erstellen. Hier ist ein Blog: So verwenden Sie reguläre Ausdrücke zum Parsen
verschachtelter
@ HenryHenrinson: Oh ja, dumm mich, wir sind uns einig :-)
Peter Thoeny
-1

Ich habe dieses Javascript-Skript erstellt, um eine CSV in Zeichenfolge zu Array-Objekt zu analysieren. Ich finde es besser, die gesamte CSV in Zeilen, Felder aufzuteilen und entsprechend zu verarbeiten. Ich denke, dass es Ihnen leicht fällt, den Code an Ihre Bedürfnisse anzupassen.

Ich hoffe es hilft dir. Vielen Dank.

    //
    //
    // 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'
        }
    }
Gabriel Chung
quelle
-3

Warum nicht einfach .split (',') verwenden?

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

var str="How are you doing today?";
var n=str.split(" "); 
Micah
quelle
2
Warum ist das eine schlechte Antwort? Es ist nativ, platziert String-Inhalt in funktionsfähigen Array ...
Micah
20
Viele Gründe. Erstens werden die doppelten Anführungszeichen für begrenzte Werte nicht entfernt. Behandelt keine Zeilenaufteilung. Entgeht keinen doppelten Anführungszeichen, die verwendet werden, um doppelte Anführungszeichen zu vermeiden, die in begrenzten Werten verwendet werden. Erlaubt keine leeren Werte. etc, etc ... Die Flexibilität des CSV-Formats macht es sehr einfach zu bedienen, aber schwierig zu analysieren. Ich werde dies nicht ablehnen, sondern nur, weil ich konkurrierende Antworten nicht ablehne.
Evan Plaice
1
Was ist, wenn Sie auf einen Wert stoßen, der ein Zeilenumbruchzeichen enthält? Eine einfache Aufteilungsfunktion interpretiert sie fälschlicherweise als das Ende eines Eintrags, anstatt ihn wie gewünscht zu überspringen. Das Parsen von CSV ist viel komplizierter als nur das Bereitstellen von zwei geteilten Routinen (eine für Zeilenumbrüche, eine für Trennzeichen).
Evan Plaice
2
(cont) Auch die Aufteilung auf Nullwerte (a, null ,, value) gibt nichts zurück, während eine leere Zeichenfolge zurückgegeben werden sollte. Verstehen Sie mich nicht falsch, Split ist ein guter Anfang, wenn Sie zu 100% sicher sind, dass die eingehenden Daten den Parser nicht beschädigen. Die Erstellung eines robusten Parsers, der alle Daten verarbeiten kann, die RFC 4801-kompatibel sind, ist jedoch erheblich komplizierter.
Evan Plaice
8
Evan, ich finde deine Javascript-Bibliothek großartig. Aber hier ist eine andere Perspektive - ich habe diese Antwort sehr geschätzt, da ich einfach eine Reihe von Zahlen auf sehr vorhersehbare Weise speichere. Es ist mir viel wichtiger, eine garantierte browserübergreifende Javascript-Kompatibilität und Wartbarkeit so weit wie möglich in der Zukunft zu gewährleisten, als eine große (wenn auch gut geschriebene und getestete) Bibliothek einzuschließen. Unterschiedliche Bedürfnisse erfordern unterschiedliche Ansätze. Wenn ich jemals echte CSV-Leistung benötige, werde ich mich definitiv dazu verpflichten, Ihre Bibliothek zu nutzen! :-)
Moodboom