सीएसवी डेटा पार्स करने के लिए जावास्क्रिप्ट कोड


216

क्या किसी को पता है कि मुझे CSV डेटा पार्स करने के लिए कुछ जावास्क्रिप्ट कोड कहां मिल सकता है?


3
इस उत्तर पर एक नज़र डालें, इसके अच्छे उत्तर हैं: stackoverflow.com/questions/8493195/…
Dobes Vandermeer

14
नीचे दिए गए अधिकांश उत्तर सिर्फ एंडी द्वारा एक तरफ से गलत हैं। पैटर्न मिलान या विभाजन का उपयोग करने वाले किसी भी उत्तर को विफल करने के लिए बर्बाद किया जाता है - वे बच अनुक्रमों का समर्थन नहीं करेंगे। उसके लिए, आपको एक परिमित राज्य मशीन की आवश्यकता है।
greg.kindel

3
जावास्क्रिप्ट और पापा पार्स के साथ एक स्थानीय CSV फ़ाइल पार्स करना: joyofdata.de/blog/…
Raffael

4
पापा पार्स बहुत सारी विशेषताओं के साथ एक और विकल्प है (बहु-थ्रेडेड, हेडर पंक्ति समर्थन, ऑटो-डिटेक्ट सीमांकक, और अधिक)
हेनरिक

1
PapaParse के लिए एक और वोट, मैं इसे AngularJS के साथ उपयोग कर रहा हूं और यह बहुत अच्छा काम करता है।
दिमित्री बुस्लाव

जवाबों:


257

आप इस ब्लॉग प्रविष्टि में उल्लिखित CSVToArray () फ़ंक्शन का उपयोग कर सकते हैं ।

<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
यह एम्बेडेड कॉमा, उद्धरण और लाइन विराम को संभाल सकता है, उदाहरण के लिए: var csv = 'id, value \ n1, James \ n02, "जिमी स्मिथ, Esq।" \ n003, "जेम्स" "जिमी" "Smith, III \"। n0004, "James \ nSmith \ nWuz यहाँ" "var array = CSVToArray (सीएसवी,", ");
प्रोटोटाइप

4
यह खाली क्षेत्रों केundefined लिए देता है जिसे उद्धृत किया जाता है । उदाहरण: मुझे देता है , लेकिन मुझे देता है । CSVToArray("4,,6")[["4","","6"]]CSVToArray("4,\"\",6")[["4",undefined,"6"]]
पैंग

3
मैं फ़ायरफ़ॉक्स में इस के साथ मुद्दों था, और स्क्रिप्ट अनुत्तरदायी बन गया है। यह केवल कुछ ही उपयोगकर्ताओं को प्रभावित करता था, इसलिए इसका कारण नहीं खोज सके
JDandChips

8
रेगेक्स में एक बग है: "([^\"\\"होना चाहिए "([^\\"। अन्यथा एक अनारक्षित मूल्य में कहीं भी एक डबल उद्धरण समय से पहले समाप्त हो जाएगा। यह मुश्किल रास्ता मिला ...
वाल्टर ट्रॉस

5
किसी को भी उपरोक्त विधि के एक कम संस्करण की तलाश में, regex ठीक से ऊपर लागू वर्णित के लिए: gist.github.com/Jezternz/c8e9fafc2c114e079829974e3764db75
जोश Mc

147

jQuery-सीएसवी

यह एक जावास्क्रिप्ट प्लगइन है जिसे CSV को जावास्क्रिप्ट डेटा में पार्स करने के लिए एंड-टू-एंड समाधान के रूप में काम करने के लिए डिज़ाइन किया गया है। यह RFC 4180 में प्रस्तुत किए गए हर एक किनारे के मामले को संभालता है , साथ ही कुछ जो एक्सेल / Google स्प्रेडशीट निर्यात के लिए पॉप अप करता है (यानी ज्यादातर शून्य मान शामिल है) कि कल्पना गायब है।

उदाहरण:

ट्रैक, कलाकार, एल्बम, साल

खतरनाक, 'बुस्टा राइम्स', 'व्हेन डिजास्टर स्ट्राइक्स', 1997

// calling this
music = $.csv.toArrays(csv)

// outputs...
[
  ["track","artist","album","year"],
  ["Dangerous","Busta Rhymes","When Disaster Strikes","1997"]
]

console.log(music[1][2]) // outputs: 'When Disaster Strikes'

अपडेट करें:

अरे हाँ, मुझे शायद यह भी उल्लेख करना चाहिए कि यह पूरी तरह से विन्यास योग्य है।

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

अपडेट 2:

अब यह Node.js पर भी jQuery के साथ काम करता है। तो आपके पास क्लाइंट-साइड या सर्वर-साइड पार्स करने का विकल्प एक ही समान है।

अपडेट 3:

Google कोड बंद होने के बाद से, jquery-csv को GitHub में स्थानांतरित कर दिया गया है

अस्वीकरण: मैं jQuery-CSV का लेखक भी हूं।


29
यह jQuery सीएसवी क्यों है? यह jQuery पर क्यों निर्भर करता है? मेरे पास स्रोत के माध्यम से एक त्वरित स्कैन है ... ऐसा नहीं लगता कि आप jQuery का उपयोग कर रहे हैं
paulslater19

17
@ paulslater19 प्लगइन jquery पर निर्भर नहीं करता है। बल्कि, यह सामान्य jQuery के विकास दिशानिर्देशों का पालन करता है। शामिल किए गए सभी तरीके स्थिर हैं और अपने स्वयं के नामस्थान (यानी $ .csv) के तहत रहते हैं। JQuery के बिना उनका उपयोग करने के लिए बस एक वैश्विक $ वस्तु बनाएं जो प्लगइन प्रारंभ के दौरान बांध देगा।
इवान प्लाइस

2
है csvसमाधान कोड में उल्लेख करने के लिए .csv filename? मैं एक अच्छा JS / JQuery उपकरण में एक सीएसवी फ़ाइल पार्स करने के लिए इच्छुक हूँ
शेख़ीहिप्पो

1
@bouncingHippo उदाहरण में, यह सिर्फ सीएसवी डेटा के एक स्ट्रिंग की बात कर रहा है, लेकिन HTML5 फ़ाइल एपीआई का उपयोग करके ब्राउज़र में स्थानीय रूप से सीएसवी फाइलें खोलने के लिए उपयोग किया जा सकता है। एक्शन jquery-csv.googlecode.com/git/examples/file-handling.html में इसका एक उदाहरण है ।
इवान प्लाइस

1
यह देखते हुए कि यह jQuery पर निर्भर नहीं है, यह वैश्विक "$" निर्भरता को दूर करने के लिए बेहतर होगा और उपयोगकर्ताओं को किसी भी वस्तु संदर्भ को पास करने दें जो वे चाहते हैं। शायद jQuery के लिए डिफ़ॉल्ट अगर यह उपलब्ध है। अन्य पुस्तकालय हैं जो "$" का उपयोग करते हैं और इसका उपयोग विकास टीमों द्वारा उन पुस्तकालयों की न्यूनतम प्रॉक्सी के साथ किया जा सकता है।
रॉब जूल

40

मेरे पास एक स्प्रेडशीट परियोजना के भाग के रूप में एक कार्यान्वयन है

इस कोड का अभी तक पूरी तरह से परीक्षण नहीं किया गया है, लेकिन इसका उपयोग करने के लिए किसी का भी स्वागत है।

हालाँकि, कुछ उत्तर दिए गए हैं, यदि आपका वास्तव में DSV या TSV फ़ाइल है, तो आपका कार्यान्वयन बहुत सरल हो सकता है , क्योंकि वे मानों में रिकॉर्ड और फ़ील्ड विभाजकों के उपयोग को रोकते हैं। दूसरी ओर CSV में वास्तव में एक क्षेत्र के अंदर अल्पविराम और नए अंक हो सकते हैं, जो अधिकांश रेगेक्स और विभाजन-आधारित दृष्टिकोणों को तोड़ता है।

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
यह मेरे पसंदीदा उत्तरों में से एक है। यह एक वास्तविक पार्सर है जिसमें बहुत सारे कोड नहीं हैं।
ट्रेवर डिक्सन

1
यदि एक अल्पविराम को एक पंक्ति के अंत में रखा जाता है, तो एक खाली सेल को इसका पालन करना चाहिए। यह कोड सिर्फ अगली पंक्ति तक जाता है, जिसके परिणामस्वरूप एक undefinedसेल होता है। उदाहरण के लिए,console.log(CSV.parse("first,last,age\r\njohn,doe,"));
skibulk

इसके अलावा, खाली कोशिकाओं को खाली तारों के लिए पार्स करना चाहिए। यह कोड उन्हें शून्य में console.log(CSV.parse("0,,2,3"));
डालता

@skibulk आपकी दूसरी टिप्पणी गलत है (कम से कम क्रोम आपके उदाहरण के साथ ठीक काम करता है)। आपकी पहली टिप्पणी हालांकि मान्य है, हालांकि यह आसानी से तय हो गई है - इससे पहले निम्न अधिकार जोड़ें if ('\r' === chars[c]) { ... }:if (end === c-1) { row.push(reviver(table.length-1, row.length, '')); }
कोडरफ़ॉर्फ़िन

35

यहाँ एक अत्यंत सरल CSV पार्सर है जो अल्पविराम, नई पंक्तियों के साथ उद्धृत क्षेत्रों को संभालता है और दोहरे उद्धरण चिह्नों से बच जाता है। कोई विभाजन या RegEx नहीं है। यह एक बार में इनपुट स्ट्रिंग 1-2 वर्णों को स्कैन करता है और एक सरणी बनाता है।

इसका परीक्षण 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;
}

इसका सरल और यह मेरे लिए काम करता है, केवल एक चीज जिसे मैंने बदला था वह मूल्य में एक ट्रिम () जोड़ रहा था :)
JustEngland

3
यह क्लीनर और अधिक सीधे आगे लगता है। मुझे 4mb फ़ाइल को पार्स करना था और अन्य उत्तर मुझे ie8 में क्रैश कर गए, लेकिन इसने इसे प्रबंधित किया।
चार्ल्स क्लेटन

3
यह भी मेरे लिए काम किया। हालांकि लाइन फीड्स की उचित हैंडलिंग की अनुमति देने के लिए मुझे एक संशोधन करना पड़ा:if (cc == '\r' && nc == '\n' && !quote) { ++row; col = 0; ++c; continue; } if (cc == '\n' && !quote) { ++row; col = 0; continue; }
user655063

1
एक अन्य उपयोगकर्ता (@ sorin-postelnicu) ने परिणाम को शब्दकोश वस्तु में बदलने के लिए एक साथी फ़ंक्शन को मदद से प्रकाशित किया: jsfiddle.net/8t2po6wh
ट्रेवर डिक्सन

1
हाँ, कभी भी गति की आवश्यकता होती है या स्मृति पैरों के निशान मायने रखते हैं, इस तरह का एक साफ समाधान कहीं बेहतर है। राज्य मशीन-एस्क पार्सिंग इतना चिकना है।
ताताराइज़ करें

14

यहाँ मेरा PEG (.js) व्याकरण है जो RFC 4180 पर ठीक लगता है (यानी यह http://en.wikipedia.org/wiki/Comma-separated_values पर उदाहरणों को संभालता है ):

start
  = [\n\r]* first:line rest:([\n\r]+ data:line { return data; })* [\n\r]* { rest.unshift(first); return rest; }

line
  = first:field rest:("," text:field { return text; })*
    & { return !!first || rest.length; } // ignore blank lines
    { rest.unshift(first); return rest; }

field
  = '"' text:char* '"' { return text.join(''); }
  / text:[^\n\r,]* { return text.join(''); }

char
  = '"' '"' { return '"'; }
  / [^"]

इसे http://jsfiddle.net/knvzk/10 या http://pegjs.majda.cz/online पर आज़माएं । उत्पन्न पार्सर को https://gist.github.com/3362830 पर डाउनलोड करें


2
खूंटी? एएसटी का निर्माण नहीं कर रहा है टाइप III व्याकरण के लिए एक भारी मेमोरी। क्या यह उन फ़ील्ड्स को संभाल सकता है जिनमें न्यूलाइन चर होते हैं क्योंकि यह 'नियमित व्याकरण' पार्सर में कवर करने के लिए सबसे कठिन मामला है। किसी भी तरह, एक उपन्यास दृष्टिकोण के लिए +1।
इवान प्लाइस

1
हां, यह एक क्षेत्र के अंदर नई रेखा को संभालता है।
ट्रेवर डिक्सन

2
अच्छा ... उस अकेले के साथ, मैंने अब तक देखे गए सभी कार्यान्वयनों में से 95% से बेहतर है। यदि आप पूर्ण आरएफसी अनुपालन की जांच करना चाहते हैं, तो यहां परीक्षण ( jquery-csv.googlecode.com/git/test/test.html ) पर एक नज़र डालें ।
इवान प्लाइस

6
बहुत बढ़िया। मुझे खूंटी में बदलने के लिए +1। मैं पार्सर-जनरेटर से प्यार करता हूं। "पांच दिनों में हाथ से कार्यक्रम क्यों आप अपने जीवन के पांच साल को स्वचालित कर सकते हैं?" - टेरेंस
पर्र

14

csvToArray v1.3

एक कॉम्पैक्ट (645 बाइट्स) लेकिन RFC4180 मानक के अनुरूप CSV स्ट्रिंग को 2D सरणी में परिवर्तित करने के लिए कार्य करता है।

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

सामान्य उपयोग: jQuery

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

सामान्य उपयोग: जावास्क्रिप्ट

csvAsArray = csvAsString.csvToArray();

क्षेत्र विभाजक को ओवरराइड करें

csvAsArray = csvAsString.csvToArray("|");

ओवरराइड रिकॉर्ड सेपरेटर

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

ओवरराइड स्किप हैडर

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

सभी को ओवरराइड करें

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

यह दिलचस्प लगता है लेकिन मुझे अब कोड नहीं मिल रहा है। क्या आप इसे फिर से पोस्ट कर सकते हैं?
सैम वाटकिंस

1
मैंने वर्तमान लिंक के साथ मुख्य पोस्ट को अपडेट किया है। बहुत धन्यवाद।
dt192

3

मुझे यकीन नहीं है कि मैं क्यों कीर्तन पूर्व नहीं कर सकता। मेरे लिए काम करना। ऐसा लगता था कि खाली खेतों या शायद कमिंग ट्रेल्स वाले खेतों पर ...

यह एक दोनों को संभालने के लिए लगता है।

मैंने पार्सर कोड नहीं लिखा था, फ़ाइल के लिए यह काम करने के लिए पार्सर फ़ंक्शन के चारों ओर सिर्फ एक आवरण। गुण देखें

    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

बचाव के लिए नियमित अभिव्यक्ति! कोड की ये कुछ पंक्तियाँ 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' ] ]

आपको lex / yacc जैसे पार्सर-जनरेटर की आवश्यकता नहीं है। रेगुलर एक्सप्रेशन RFC 4180 को ठीक से पॉजिटिव लुकबाइंड, नेगेटिव लुकबाइंड और पॉजिटिव लुकहैड की बदौलत हैंडल करता है।

Https://github.com/peterthoeny/parse-csv-js पर क्लोन / डाउनलोड कोड


Regexps को परिमित राज्य मशीनों के उपयोग से कार्यान्वित किया जाता है, इसलिए आप वास्तव में FSM की आवश्यकता है।
हेनरी हेनरिंसन

@ हेनरीहिंसन: जरूरी नहीं। मैं आपको उपरोक्त कोड के साथ एक समस्या खोजने के लिए चुनौती देता हूं। मैं इसका उत्पादन में उपयोग करता हूं। नियमित अभिव्यक्तियों के साथ अधिक जटिल पार्स करना भी संभव है। सिंटैक्स ट्री बनाने के लिए आपको LL पार्सर की आवश्यकता नहीं है। यहाँ एक ब्लॉग है: कैसे नेस्टेड संरचनाओं को पार्स करने के लिए नियमित अभिव्यक्तियों का उपयोग करें, twiki.org/cgi-bin/view/Blog/BlogEntry201109x3
पीटर थोनी

@ हेनरीहेनरिंसन: ओह, हाँ, मुझे डमी, हम हिंसक समझौते में हैं :-)
पीटर थोनी

-1

मैंने इस जावास्क्रिप्ट स्क्रिप्ट का निर्माण स्ट्रिंग ऑब्जेक्ट ऑब्जेक्ट में CSV को पार्स करने के लिए किया है। मुझे संपूर्ण CSV को लाइनों, क्षेत्रों में तोड़ना और उनके अनुसार उन्हें संसाधित करना बेहतर लगता है। मुझे लगता है कि इससे आपको अपनी जरूरत के हिसाब से कोड बदलने में आसानी होगी।

मुझे आशा है कि यह आपकी मदद करेगा। धन्यवाद।

    //
    //
    // CSV to object
    //
    //

    const new_line_char = '\n';
    const field_separator_char = ',';

    function parse_csv(csv_str) {

        var result = [];

        let line_end_index_moved = false;
        let line_start_index = 0;
        let line_end_index = 0;
        let csr_index = 0;
        let cursor_val = csv_str[csr_index];
        let found_new_line_char = get_new_line_char(csv_str);
        let in_quote = false;

        // handle \r\n
        if (found_new_line_char == '\r\n') {
            csv_str = csv_str.split(found_new_line_char).join(new_line_char);
        }
        // handle 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

सिर्फ .plit (',') का उपयोग क्यों नहीं किया जाता है?

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

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

2
यह एक बुरा जवाब क्यों है? यह मूल है, स्ट्रिंग सामग्री को व्यावहारिक सरणी में रखता है ...
मीका

20
बहुत सारे कारण। सबसे पहले, यह सीमांकित मानों पर दोहरे उद्धरण नहीं हटाता है। लाइन विभाजन को नहीं संभालता है। सीमांकित मूल्यों में प्रयुक्त दोहरे उद्धरणों से बचने के लिए उपयोग किए जाने वाले दोहरे-दोहरे उद्धरणों से बच नहीं जाता है। खाली मूल्यों की अनुमति नहीं देता है। आदि, ... सीएसवी प्रारूप का लचीलापन इसे उपयोग करना बहुत आसान बनाता है लेकिन पार्स करना मुश्किल है। मैं इसे नीचा नहीं दिखाऊंगा, लेकिन केवल इसलिए कि मैं प्रतिस्पर्धा के उत्तरों को कम नहीं करता।
इवान प्लाइस

1
जब आप एक वैल्यू का सामना करते हैं, जिसमें एक न्यूलाइन चार्ट होता है? एक साधारण विभाजन फ़ंक्शन इसे गलत तरीके से एक प्रविष्टि के अंत के रूप में व्याख्या करेगा, इसके बजाय इसे छोड़ देना चाहिए। पार्सिंग सीएसवी केवल 2 स्प्लिट रूटीन प्रदान करने की तुलना में बहुत अधिक जटिल है (एक नई सूची के लिए, एक सीमांकक के लिए)।
इवान प्लाइस

2
(cont) इसके अलावा अशक्त मानों (a, null, value) पर विभाजित होता है, जबकि खाली स्ट्रिंग को वापस नहीं करना चाहिए। मुझे गलत मत समझो, विभाजन एक अच्छी शुरुआत है यदि आप 100% सकारात्मक हैं कि आने वाले डेटा पार्सर को नहीं तोड़ेंगे, लेकिन एक मजबूत पार्सर बना सकते हैं जो किसी भी डेटा को संभाल सकता है जो कि RFC 4801 अनुरूप है, काफी अधिक जटिल है।
इवान प्लाइस

8
इवान, मुझे लगता है कि आपकी जावास्क्रिप्ट लाइब्रेरी बहुत बढ़िया है। लेकिन यहां एक और परिप्रेक्ष्य है - मैंने इस जवाब की सराहना की, क्योंकि मैं बस एक बहुत ही पूर्वानुमानित अंदाज में संख्याओं की एक श्रृंखला का भंडारण कर रहा हूं। मेरे लिए यह बहुत महत्वपूर्ण है कि हम क्रॉस-ब्राउज़र जावास्क्रिप्ट अनुकूलता और भविष्य में जहाँ तक संभव हो, एक बड़ी (यद्यपि अच्छी तरह से लिखित और अच्छी तरह से जाँच की गई) लाइब्रेरी की तुलना में स्थिरता बनाए रखें। अलग-अलग जरूरतों के लिए अलग-अलग तरीकों की जरूरत होती है। अगर मुझे कभी वास्तविक CSV शक्ति की आवश्यकता होती है, तो मैं निश्चित रूप से आपके पुस्तकालय का उपयोग करने के लिए प्रतिबद्ध होऊंगा! :-)
मूडबुक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.