Kod JavaScript do analizy danych CSV

217

Czy ktoś ma pomysł, gdzie mogę znaleźć kod javascript do analizy danych CSV?

Pierre-Gilles Levallois
źródło
3
Spójrz na tę odpowiedź tutaj, ma dobre odpowiedzi: stackoverflow.com/questions/8493195/…
Dobes Vandermeer
14
Większość poniższych odpowiedzi jest po prostu błędna, oprócz tych Andy'ego. Każda odpowiedź, która używa dopasowania wzorca lub podziałów, jest skazana na niepowodzenie - nie będą obsługiwać sekwencji ucieczki. Do tego potrzebujesz skończonej maszyny stanów.
greg.kindel
3
Analiza lokalnego pliku CSV za pomocą JavaScript i analizy Papa: joyofdata.de/blog/…
Raffael
4
Papa Parse to kolejna opcja z wieloma funkcjami (wielowątkowa, obsługa wiersza nagłówka, automatyczne wykrywanie ogranicznika i inne)
Hinrich
1
Kolejny głos na PapaParse, używam go z AngularJS i działa świetnie.
Dmitrij Buslaev,

Odpowiedzi:

258

Możesz użyć funkcji CSVToArray () wspomnianej w tym wpisie na blogu.

<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
źródło
1
Może to obsługiwać osadzone przecinki, cytaty i podziały wierszy, np .: var csv = 'id, wartość \ n1, James \ n02, "Jimmy Smith, Esq." \ N003, "James" "Jimmy" "Smith, III" \ n0004, „James \ nSmith \ nWuz tutaj” var array = CSVToArray (csv, „,”);
prototyp
4
Daje undefineddo pustych pól , które są cytowane . Przykład: CSVToArray("4,,6")daje mi [["4","","6"]], ale CSVToArray("4,\"\",6")daje mi [["4",undefined,"6"]].
Pang
3
Miałem z tym problemy w Firefoksie, a skrypt przestał reagować. Wydawało się, że dotyczy to tylko kilku użytkowników, więc nie mogłem znaleźć przyczyny
dotyczyło JDandChips
8
W wyrażeniu regularnym występuje błąd: "([^\"\\"powinien być "([^\\". W przeciwnym razie podwójny cytat w dowolnym miejscu w niecytowanej wartości przedwcześnie go zakończy. Znalazłem to na
własnej skórze
5
Dla każdego, kto szuka zredukowanej wersji powyższej metody, z zastosowaną poprawką wyrażenia regularnego opisaną powyżej: gist.github.com/Jezternz/c8e9fafc2c114e079829974e3764db75
Josh Mc
147

jQuery-CSV

Jest to wtyczka jquery zaprojektowana jako kompleksowe rozwiązanie do analizowania CSV w danych Javascript. Obsługuje każdy pojedynczy przypadek krawędzi przedstawiony w RFC 4180 , a także niektóre wyskakujące okienka dla eksportu Excel / Google Spreadsheed (tj. Głównie zawierające wartości zerowe), których brakuje w specyfikacji.

Przykład:

utwór, artysta, album, rok

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'

Aktualizacja:

O tak, powinienem również wspomnieć, że jest całkowicie konfigurowalny.

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

Aktualizacja 2:

Teraz działa również z jQuery na Node.js. Masz więc możliwość parsowania po stronie klienta lub po stronie serwera przy użyciu tej samej biblioteki.

Aktualizacja 3:

Od czasu zamknięcia kodu Google plik jquery-csv został migrowany do GitHub .

Oświadczenie: Jestem także autorem jQuery-CSV.

Evan Plaice
źródło
29
Dlaczego jest to jQuery csv? Dlaczego to zależy od jQuery? Miałem szybkie skanowanie źródła ... nie wygląda na to, że używasz jQuery
paulslater19
17
@ paulslater19 Wtyczka nie zależy od jquery. Raczej postępuje zgodnie ze wspólnymi wytycznymi dotyczącymi programowania jQuery. Wszystkie uwzględnione metody są statyczne i znajdują się we własnej przestrzeni nazw (tj. $ .Csv). Aby użyć ich bez jQuery, po prostu stwórz globalny obiekt $, z którym wtyczka będzie się wiązać podczas inicjalizacji.
Evan Plaice,
2
jest csvw kodzie rozwiązania odnoszą się do .csv filename? jestem zainteresowany dobrym narzędziem JS / JQuery do parsowania pliku csv
bouncingHippo
1
@ bouncingHippo W tym przykładzie chodzi tylko o ciąg danych csv, ale biblioteki lib można używać do otwierania plików csv lokalnie w przeglądarce za pomocą interfejsu API plików HTML5. Oto przykład tego działania jquery-csv.googlecode.com/git/examples/file-handling.html .
Evan Plaice,
1
Biorąc pod uwagę, że nie jest to zależne od jQuery, lepiej byłoby usunąć globalną zależność „$” i pozwolić użytkownikom na przekazywanie dowolnych odniesień do obiektów. Być może domyślnie jQuery, jeśli jest dostępny. Istnieją inne biblioteki, które używają „$” i mogą być używane przez zespoły programistów z minimalnymi serwerami proxy tych bibliotek.
RobG
40

Mam implementację w ramach projektu arkusza kalkulacyjnego.

Ten kod nie został jeszcze dokładnie przetestowany, ale każdy może go używać.

Jak zauważono w niektórych odpowiedziach, implementacja może być znacznie prostsza, jeśli faktycznie masz plik DSV lub TSV , ponieważ uniemożliwiają one użycie separatora rekordów i pól w wartościach. Z drugiej strony CSV może zawierać przecinki i znaki nowej linii w polu, co łamie większość metod wyrażeń regularnych i podzielonych.

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
źródło
9
To jedna z moich ulubionych odpowiedzi. To prawdziwy parser zaimplementowany w niezbyt dużej ilości kodu.
Trevor Dixon,
1
Jeśli przecinek zostanie umieszczony na końcu wiersza, pusta komórka powinna za nim podążać. Ten kod po prostu przeskakuje do następnego wiersza, w wyniku czego powstaje undefinedkomórka. Na przykładconsole.log(CSV.parse("first,last,age\r\njohn,doe,"));
skibulk
Ponadto puste komórki powinny analizować puste ciągi. Ten kod analizuje je na zera, co jest mylące, ponieważ komórki mogą faktycznie zawierać zera:console.log(CSV.parse("0,,2,3"));
skibulk
@skibulk Twój drugi komentarz jest niepoprawny (przynajmniej w Chrome działa dobrze z Twoim przykładem). Twój pierwszy komentarz jest jednak poprawny, chociaż można go łatwo naprawić - dodaj następujące przed if ('\r' === chars[c]) { ... }:if (end === c-1) { row.push(reviver(table.length-1, row.length, '')); }
coderforlife
35

Oto niezwykle prosty parser CSV, który obsługuje pola cytowane przecinkami, nowe wiersze i znaki cudzysłowu. Nie ma podziału ani RegEx. Skanuje wejściowy ciąg 1-2 znaków na raz i buduje tablicę.

Przetestuj to na stronie 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
źródło
To proste i działa dla mnie, jedyną rzeczą, którą zmieniłem, było dodanie trim () do wartości :)
JustEngland
3
Wydaje się to czystsze i bardziej bezpośrednie. Musiałem przeanalizować plik 4 MB, a inne odpowiedzi zawiesiły się na mnie w ie8, ale udało się to.
Charles Clayton
3
To również działało dla mnie. Musiałem jednak dokonać jednej modyfikacji, aby umożliwić poprawną obsługę kanałów:if (cc == '\r' && nc == '\n' && !quote) { ++row; col = 0; ++c; continue; } if (cc == '\n' && !quote) { ++row; col = 0; continue; }
user655063
1
Inny użytkownik (@ sorin-postelnicu) opublikował pomocniczą funkcję służącą do przekształcenia wyniku w obiekt słownika: jsfiddle.net/8t2po6wh .
Trevor Dixon,
1
Tak, za każdym razem, gdy potrzebna jest prędkość lub ślady pamięci mają znaczenie, takie czyste rozwiązanie jest o wiele lepsze. Stanowe parsowanie maszynowe jest o wiele płynniejsze.
Tatarize
14

Oto moja gramatyka PEG (.js), która wydaje się działać poprawnie na RFC 4180 (tzn. Obsługuje przykłady na 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 '"'; }
  / [^"]

Wypróbuj na http://jsfiddle.net/knvzk/10 lub http://pegjs.majda.cz/online . Pobierz wygenerowany analizator składni ze strony https://gist.github.com/3362830 .

Trevor Dixon
źródło
2
KOŁEK? Nie buduje AST trochę ciężkiej pamięci dla gramatyki typu III. Czy poradzi sobie z polami zawierającymi znaki nowej linii, ponieważ jest to najtrudniejszy przypadek do uwzględnienia w parserze „zwykłej gramatyki”. Tak czy inaczej +1 za nowatorskie podejście.
Evan Plaice,
1
Tak, obsługuje znak nowej linii w polu.
Trevor Dixon
2
Fajnie ... Dzięki temu samemu jest to ponad 95% wszystkich wdrożeń, jakie kiedykolwiek widziałem. Jeśli chcesz sprawdzić pełną zgodność z RFC, spójrz na testy tutaj ( jquery-csv.googlecode.com/git/test/test.html ).
Evan Plaice,
6
Dobrze rozegrane. +1 za włączenie mnie do PEG. Uwielbiam generatory parserów. „Po co ręcznie programować w ciągu pięciu dni, co możesz spędzić pięć lat swojego życia na automatyzacji?” - Terence Parr, ANTLR
Subfuzion
14

csvToArray v1.3

Kompaktowa (645 bajtów), ale zgodna funkcja do konwersji łańcucha CSV na tablicę 2D, zgodną ze standardem RFC4180.

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

Wspólne użycie: jQuery

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

Typowe zastosowanie: JavaScript

csvAsArray = csvAsString.csvToArray();

Zastąp separator pól

csvAsArray = csvAsString.csvToArray("|");

Zastąp separator rekordów

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

Zastąp pominięcie nagłówka

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

Zastąp wszystko

csvAsArray = csvAsString.csvToArray("|", "#", 1);
dt192
źródło
Brzmi interesująco, ale nie mogę teraz znaleźć kodu. Czy możesz to opublikować ponownie?
Sam Watkins,
1
Zaktualizowałem główny post aktualnym linkiem. Wielkie dzięki.
dt192
3

Nie jestem pewien, dlaczego nie mogłem ex Kirtans. pracować dla mnie. Wydawało się, że zawodzi na pustych polach, a może na polach z przecinkami ...

Ten wydaje się obsługiwać oba.

Nie napisałem kodu parsera, tylko opakowanie wokół funkcji parsera, aby działało to dla pliku. patrz Uznanie autorstwa

    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
źródło
1

Wyrażenia regularne na ratunek! Te kilka wierszy kodu obsługuje poprawnie cytowane pola z osadzonymi przecinkami, cudzysłowami i znakami nowej linii w oparciu o standard 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' ] ]

Nie potrzebujesz generatora analizatora składni, takiego jak lex / yacc. Wyrażenie regularne poprawnie obsługuje RFC 4180 dzięki pozytywnemu wyglądowi, negatywnemu wyglądowi i pozytywnemu spojrzeniu w przód.

Sklonuj / pobierz kod na https://github.com/peterthoeny/parse-csv-js

Peter Thoeny
źródło
Regeksy są implementowane za pomocą skończonych maszyn stanów, więc w rzeczywistości potrzebujesz FSM.
Henry Henrinson
@HenryHenrinson: Niekoniecznie. Wzywam cię do znalezienia problemu z powyższym kodem. Używam go w produkcji. Można także wykonywać bardziej złożone analizy składniowe za pomocą wyrażeń regularnych. Nie potrzebujesz parsera LL, aby utworzyć drzewo składniowe. Oto blog: Jak używać wyrażeń regularnych do analizowania
Peter Thoeny
@HenryHenrinson: Och, tak, obezwładnij mnie, jesteśmy w brutalnej umowie :-)
Peter Thoeny
-1

Skonstruowałem ten skrypt javascript do analizowania pliku CSV w postaci ciągu na obiekt tablicy. Uważam, że lepiej jest podzielić cały CSV na linie, pola i odpowiednio je przetworzyć. Myślę, że ułatwi ci to zmianę kodu w zależności od potrzeb.

Mam nadzieję, że ci to pomoże. Dzięki.

    //
    //
    // 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
źródło
-3

Dlaczego nie użyć po prostu .split (',')?

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

var str="How are you doing today?";
var n=str.split(" "); 
Micheasz
źródło
2
Dlaczego to zła odpowiedź? Jest natywny, umieszcza ciąg znaków w wykonalnej tablicy ...
Micheasza
20
Wiele powodów. Po pierwsze, nie usuwa podwójnych cudzysłowów na wartościach rozdzielanych. Nie obsługuje podziału linii. Nie unika podwójnych podwójnych cudzysłowów używanych do unikania podwójnych cudzysłowów używanych w wartościach rozdzielanych. Nie zezwala na puste wartości. etc, etc ... Elastyczność formatu CSV sprawia, że ​​jest bardzo łatwy w użyciu, ale trudny do przeanalizowania. Nie będę głosować za tym, ale tylko dlatego, że nie głosuję za odrzuceniem konkurencyjnych odpowiedzi.
Evan Plaice,
1
A jeśli napotkasz wartość zawierającą znak nowej linii? Prosta funkcja podziału niepoprawnie interpretuje ją jako koniec wpisu zamiast przeskakiwać nad nią tak, jak powinna. Analiza pliku CSV jest o wiele bardziej skomplikowana niż tylko udostępnienie 2 procedur podziału (jednej dla znaków nowej linii, drugiej dla ograniczników).
Evan Plaice,
2
(ciąg dalszy) Również podział na wartości null (a, null ,, wartość) nic nie zwraca, podczas gdy powinien zwracać pusty ciąg. Nie zrozum mnie źle, podział jest dobrym początkiem, jeśli masz 100% pewności, że przychodzące dane nie spowodują uszkodzenia analizatora składni, ale utworzenie solidnego analizatora składni, który poradzi sobie z dowolnymi danymi zgodnymi z RFC 4801, jest znacznie bardziej skomplikowane.
Evan Plaice,
8
Evan, myślę, że twoja biblioteka javascript jest niesamowita. Ale oto inna perspektywa - doceniam tę odpowiedź, ponieważ po prostu przechowuję serię liczb w bardzo przewidywalny sposób. O wiele ważniejsze jest dla mnie zagwarantowanie kompatybilności między przeglądarkami JavaScript i łatwości konserwacji tak daleko w przyszłości, jak to możliwe, niż włączenie dużej (choć dobrze napisanej i dobrze przetestowanej) biblioteki. Różne potrzeby wymagają różnych podejść. Jeśli kiedykolwiek będę potrzebować prawdziwej mocy CSV, ZDECYDOWANIE zobowiązuję się do korzystania z twojej biblioteki! :-)
moodboom