Voorbeeld JavaScript-code om CSV-gegevens te ontleden

Waar kan ik JavaScript-code vinden om CSV-gegevens te ontleden?


Antwoord 1, autoriteit 100%

U kunt de CSVToArray()functie genoemd in dit blogbericht.

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

Antwoord 2, autoriteit 54%

jQuery-CSV

Het is een jQuery-plug-in die is ontworpen om te werken als een end-to-end-oplossing voor het parseren van CSV in JavaScript-gegevens. Het behandelt elk randgeval dat wordt gepresenteerd in RFC 4180, evenals enkele die verschijnen voor Excel/ Google-spreadsheet exporteert (dwz meestal met null-waarden) dat de specificatie ontbreekt.

Voorbeeld:

track,artiest,album,jaar

Gevaarlijk,’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'

Bijwerken:

O ja, ik moet waarschijnlijk ook vermelden dat het volledig configureerbaar is.

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

Update 2:

Het werkt nu ook met jQuery op Node.js. Je hebt dus de mogelijkheid om zowel client-side als server-side parsing uit te voeren met dezelfde bibliotheek.

Update 3:

Sinds de beëindiging van Google Code is jquery-csv gemigreerd naar GitHub.

Disclaimer: ik ben ook de auteur van jQuery-CSV.


Antwoord 3, autoriteit 14%

Hier is een uiterst eenvoudig CSV-parser die handvatten velden tussen aanhalingstekens met komma’s, nieuwe lijnen, en ontsnapte dubbele aanhalingstekens. Er is geen splitsing of reguliere expressie. Het tast de invoerstring 1-2 tekens tegelijk en bouwt een array.

Test het op 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;
}

Antwoord 4, autoriteit 14%

Ik heb een implementatieals onderdeel van een spreadsheetproject.

Deze code is nog niet grondig getest, maar iedereen mag hem gebruiken.

Zoals sommige van de antwoorden echter opmerkten, kan uw implementatie veel eenvoudiger zijn als u daadwerkelijk een DSV heeft of TSV-bestand, omdat ze het gebruik van de record- en veldscheidingstekens in de waarden niet toestaan. CSV daarentegen kan in feite komma’s en nieuwe regels in een veld bevatten, wat de meeste reguliere expressies en op splitsen gebaseerde benaderingen overtreedt.

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

Antwoord 5, Autoriteit 5%

CSVTOARRAY V1.3

Een compacte (645 bytes), maar compliant-functie om een ​​CSV-string om te zetten in een 2D-array, voldoet aan de RFC4180-norm.

https://code.google.com/Archive/p / CSV-to-array / downloads

Gemeenschappelijk gebruik: jQuery

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

Gemeenschappelijk gebruik: JavaScript

csvAsArray = csvAsString.csvToArray();

Override veldscheider

csvAsArray = csvAsString.csvToArray("|");

Record Separator negeren

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

Overschakelen Skip Header

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

overschrijft alle

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

Antwoord 6, Autoriteit 5%

Hier is mijn PEG (.js) grammatica die OK lijkt te doen bij RFC 4180 (dwz het verwerkt de voorbeelden op 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 '"'; }
  / [^"]

Probeer het uit op http://jsfiddle.net/knvzk/10of http://pegjs.majda.cz/online. Download de gegenereerde parser op https://gist.github.com/3362830.


Antwoord 7

Hier is mijn eenvoudige JavaScript-code vanille:

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
}

Antwoord 8

Ik weet niet zeker waarom ik niet kon krijgen Kirtan’s voorbeeldom voor mij te werken. Het leek te mislukken op lege velden of misschien velden met komma’s…

Deze lijkt beide aan te kunnen.

Ik heb de parsercode niet geschreven, alleen een wrapper rond de parserfunctie om dit voor een bestand te laten werken. Zie toeschrijving.

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

Antwoord 9

Regelmatige uitdrukkingen helpen je! Deze paar regels code verwerken correct geciteerde velden met ingesloten komma’s, aanhalingstekens en nieuwe regels op basis van de RFC 4180-standaard.

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

Je hebt geen parser-generator zoals lex/yacc nodig. De reguliere expressie verwerkt RFC 4180 correct dankzij positieve lookbehind, negatieve lookbehind en positive lookahead.

Kloon/download code op https://github.com/peterthoeny/parse-csv- js


Antwoord 10

Hier is nog een oplossing. Dit gebruikt:

  • een grove algemene reguliere expressie voor het splitsen van de CSV-tekenreeks (inclusief omringende aanhalingstekens en volgkomma’s)
  • fijnkorrelige reguliere expressie voor het opschonen van de omringende aanhalingstekens en volgkomma’s
  • heeft ook differentiërende tekenreeksen, getallen en booleaanse waarden voor typecorrectie

Voor de volgende invoerreeks:

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

De code geeft uit:

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

Hier is mijn implementatie van parseCSVLine() in een uitvoerbaar codefragment:

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

Antwoord 11

Ik heb dit JavaScript-script geconstrueerd om een CSV in string naar array-object te parseren. Ik vind het beter om de hele CSV op te splitsen in regels, velden en dienovereenkomstig te verwerken. Ik denk dat het u gemakkelijk zal maken om de code aan uw behoeften aan te passen.

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

Antwoord 12

Gebruik gewoon .split(','):

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

Other episodes