अस्वीकरण
2014-12-01 अपडेट: नीचे दिया गया उत्तर केवल CSV के एक बहुत विशिष्ट प्रारूप के लिए काम करता है। के रूप में सही ढंग से बताया टिप्पणी में महानिदेशक द्वारा , यह समाधान है नहीं सीएसवी के आरएफसी 4180 परिभाषा फिट और यह भी करता है नहीं माइक्रोसॉफ्ट एक्सेल प्रारूप फिट। यह समाधान केवल यह दर्शाता है कि इनपुट के एक (गैर-मानक) सीएसवी लाइन को कैसे पार्स किया जा सकता है जिसमें स्ट्रिंग प्रकारों का मिश्रण होता है, जहां तार में बच गए उद्धरण और अल्पविराम शामिल हो सकते हैं।
एक गैर-मानक सीएसवी समाधान
के रूप में austincheney सही ढंग से बताते हैं , आप वास्तव में शुरू से अंत तक स्ट्रिंग को पार्स करने की आवश्यकता है यदि आप उद्धृत किए गए वर्णों को ठीक से संभालना चाहते हैं जो बच गए अक्षर हो सकते हैं। इसके अलावा, ओपी स्पष्ट रूप से परिभाषित नहीं करता है कि वास्तव में "सीएसवी स्ट्रिंग" क्या है। पहले हमें यह निर्धारित करना चाहिए कि एक वैध सीएसवी स्ट्रिंग और उसके व्यक्तिगत मूल्य क्या हैं।
दिया गया: "सीएसवी स्ट्रिंग" परिभाषा
इस चर्चा के उद्देश्य के लिए, एक "सीएसवी स्ट्रिंग" में शून्य या अधिक मूल्य होते हैं, जहां कई मानों को अल्पविराम द्वारा अलग किया जाता है। प्रत्येक मूल्य में निम्न शामिल हो सकते हैं:
- एक डबल उद्धृत स्ट्रिंग (इसमें बिना उद्धरण के एकल उद्धरण हो सकते हैं)।
- एक सिंगल कोटेड स्ट्रिंग (इसमें अनसैप्ड डबल कोट्स हो सकते हैं)।
- एक गैर-उद्धृत स्ट्रिंग ( इसमें उद्धरण, अल्पविराम या बैकस्लैश शामिल नहीं हो सकते हैं)।
- एक खाली मान। (सभी व्हाट्सएप मूल्य को खाली माना जाता है।)
नियमों / नोट्स:
- कोट किए गए मानों में अल्पविराम हो सकते हैं।
- कोट किए गए मानों में कुछ भी हो सकता है, उदाहरण के लिए
'that\'s cool'
।
- उद्धरण, अल्पविराम या बैकस्लैश वाले मान उद्धृत किए जाने चाहिए।
- व्हाट्सएप के प्रमुख या अनुगामी वाले मानों को उद्धृत किया जाना चाहिए।
- बैकस्लैश को सभी से हटा दिया जाता है:
\'
एकल उद्धृत मूल्यों में।
- बैकलैश को सभी से हटा दिया जाता है:
\"
दोहरे उद्धृत मूल्यों में।
- गैर-उद्धृत स्ट्रिंग्स को किसी भी अग्रणी और अनुगामी रिक्त स्थान की छंटनी की जाती है।
- अल्पविराम विभाजक में आसन्न व्हाट्सएप हो सकता है (जिसे अनदेखा किया गया है)।
खोजें:
एक जावास्क्रिप्ट फ़ंक्शन जो स्ट्रिंग मानों की एक सरणी में एक मान्य CSV स्ट्रिंग (जैसा कि ऊपर परिभाषित किया गया है) को परिवर्तित करता है।
उपाय:
इस समाधान द्वारा उपयोग किए जाने वाले नियमित अभिव्यक्ति जटिल हैं। और (आईएमएचओ) सभी गैर-तुच्छ नियमित अभिव्यक्तियों को बहुत सारी टिप्पणियों और इंडेंटेशन के साथ फ्री-स्पेसिंग मोड में प्रस्तुत किया जाना चाहिए। दुर्भाग्य से, जावास्क्रिप्ट फ्री-स्पेसिंग मोड की अनुमति नहीं देता है। इस प्रकार, इस समाधान द्वारा लागू किए गए नियमित अभिव्यक्तियों को पहले देशी नियमित अभिव्यक्ति सिंटैक्स में प्रस्तुत किया जाता है (पायथन के काम r'''...'''
कच्चे-मल्टी-लाइन-सिंटैक्स का उपयोग करके व्यक्त किया गया है )।
पहले यहां एक नियमित अभिव्यक्ति है जो पुष्टि करती है कि सीवीएस स्ट्रिंग उपरोक्त आवश्यकताओं को पूरा करती है:
"CSV स्ट्रिंग" को मान्य करने के लिए नियमित अभिव्यक्ति:
re_valid = r"""
# Validate a CSV string having single, double or un-quoted values.
^ # Anchor to start of string.
\s* # Allow whitespace before value.
(?: # Group for value alternatives.
'[^'\\]*(?:\\[\S\s][^'\\]*)*' # Either Single quoted string,
| "[^"\\]*(?:\\[\S\s][^"\\]*)*" # or Double quoted string,
| [^,'"\s\\]*(?:\s+[^,'"\s\\]+)* # or Non-comma, non-quote stuff.
) # End group of value alternatives.
\s* # Allow whitespace after value.
(?: # Zero or more additional values
, # Values separated by a comma.
\s* # Allow whitespace before value.
(?: # Group for value alternatives.
'[^'\\]*(?:\\[\S\s][^'\\]*)*' # Either Single quoted string,
| "[^"\\]*(?:\\[\S\s][^"\\]*)*" # or Double quoted string,
| [^,'"\s\\]*(?:\s+[^,'"\s\\]+)* # or Non-comma, non-quote stuff.
) # End group of value alternatives.
\s* # Allow whitespace after value.
)* # Zero or more additional values
$ # Anchor to end of string.
"""
यदि एक स्ट्रिंग उपरोक्त नियमित अभिव्यक्ति से मेल खाती है, तो वह स्ट्रिंग एक मान्य CSV स्ट्रिंग है (पहले बताए गए नियमों के अनुसार) और निम्नलिखित नियमित अभिव्यक्ति का उपयोग करके पार्स किया जा सकता है। फिर निम्न नियमित अभिव्यक्ति का उपयोग CSV स्ट्रिंग से एक मान से मेल खाने के लिए किया जाता है। यह तब तक बार-बार लागू किया जाता है जब तक कि कोई अधिक मिलान नहीं मिलता है (और सभी मानों को पार्स किया गया है)।
एक मान्य CSV स्ट्रिंग से एक मान पार्स करने के लिए नियमित अभिव्यक्ति:
re_value = r"""
# Match one value in valid CSV string.
(?!\s*$) # Don't match empty last value.
\s* # Strip whitespace before value.
(?: # Group for value alternatives.
'([^'\\]*(?:\\[\S\s][^'\\]*)*)' # Either $1: Single quoted string,
| "([^"\\]*(?:\\[\S\s][^"\\]*)*)" # or $2: Double quoted string,
| ([^,'"\s\\]*(?:\s+[^,'"\s\\]+)*) # or $3: Non-comma, non-quote stuff.
) # End group of value alternatives.
\s* # Strip whitespace after value.
(?:,|$) # Field ends on comma or EOS.
"""
ध्यान दें कि एक विशेष मामला मूल्य है जो इस नियमित अभिव्यक्ति से मेल नहीं खाता है - उस मूल्य के खाली होने पर बहुत अंतिम मूल्य। इस विशेष "रिक्त अंतिम मान" मामले का परीक्षण और जावास्क्रिप्ट फ़ंक्शन द्वारा नियंत्रित किया जाता है जो निम्नानुसार है।
CSV स्ट्रिंग को पार्स करने के लिए जावास्क्रिप्ट फ़ंक्शन:
// Return array of string values, or NULL if CSV string not well formed.
function CSVtoArray(text) {
var re_valid = /^\s*(?:'[^'\\]*(?:\\[\S\s][^'\\]*)*'|"[^"\\]*(?:\\[\S\s][^"\\]*)*"|[^,'"\s\\]*(?:\s+[^,'"\s\\]+)*)\s*(?:,\s*(?:'[^'\\]*(?:\\[\S\s][^'\\]*)*'|"[^"\\]*(?:\\[\S\s][^"\\]*)*"|[^,'"\s\\]*(?:\s+[^,'"\s\\]+)*)\s*)*$/;
var re_value = /(?!\s*$)\s*(?:'([^'\\]*(?:\\[\S\s][^'\\]*)*)'|"([^"\\]*(?:\\[\S\s][^"\\]*)*)"|([^,'"\s\\]*(?:\s+[^,'"\s\\]+)*))\s*(?:,|$)/g;
// Return NULL if input string is not well formed CSV string.
if (!re_valid.test(text)) return null;
var a = []; // Initialize array to receive values.
text.replace(re_value, // "Walk" the string using replace with callback.
function(m0, m1, m2, m3) {
// Remove backslash from \' in single quoted values.
if (m1 !== undefined) a.push(m1.replace(/\\'/g, "'"));
// Remove backslash from \" in double quoted values.
else if (m2 !== undefined) a.push(m2.replace(/\\"/g, '"'));
else if (m3 !== undefined) a.push(m3);
return ''; // Return empty string.
});
// Handle special case of empty last value.
if (/,\s*$/.test(text)) a.push('');
return a;
};
उदाहरण इनपुट और आउटपुट:
निम्नलिखित उदाहरणों में, घुंघराले ब्रेसिज़ का परिसीमन करने के लिए उपयोग किया जाता है {result strings}
। (यह अग्रणी / अनुगामी स्थानों और शून्य-लंबाई के तारों की कल्पना करने में मदद करने के लिए है।)
// Test 1: Test string from original question.
var test = "'string, duppi, du', 23, lala";
var a = CSVtoArray(test);
/* Array has three elements:
a[0] = {string, duppi, du}
a[1] = {23}
a[2] = {lala} */
// Test 2: Empty CSV string.
var test = "";
var a = CSVtoArray(test);
/* Array has zero elements: */
// Test 3: CSV string with two empty values.
var test = ",";
var a = CSVtoArray(test);
/* Array has two elements:
a[0] = {}
a[1] = {} */
// Test 4: Double quoted CSV string having single quoted values.
var test = "'one','two with escaped \' single quote', 'three, with, commas'";
var a = CSVtoArray(test);
/* Array has three elements:
a[0] = {one}
a[1] = {two with escaped ' single quote}
a[2] = {three, with, commas} */
// Test 5: Single quoted CSV string having double quoted values.
var test = '"one","two with escaped \" double quote", "three, with, commas"';
var a = CSVtoArray(test);
/* Array has three elements:
a[0] = {one}
a[1] = {two with escaped " double quote}
a[2] = {three, with, commas} */
// Test 6: CSV string with whitespace in and around empty and non-empty values.
var test = " one , 'two' , , ' four' ,, 'six ', ' seven ' , ";
var a = CSVtoArray(test);
/* Array has eight elements:
a[0] = {one}
a[1] = {two}
a[2] = {}
a[3] = { four}
a[4] = {}
a[5] = {six }
a[6] = { seven }
a[7] = {} */
अतिरिक्त नोट्स:
इस समाधान के लिए आवश्यक है कि CSV स्ट्रिंग "मान्य" हो। उदाहरण के लिए, अछूता मान में बैकस्लैश या उद्धरण शामिल नहीं हो सकते हैं, उदाहरण के लिए निम्न CSV स्ट्रिंग मान्य नहीं है:
var invalid1 = "one, that's me!, escaped \, comma"
यह वास्तव में एक सीमा नहीं है क्योंकि किसी भी उप-स्ट्रिंग को एकल या दोहरे उद्धृत मूल्य के रूप में दर्शाया जा सकता है। ध्यान दें कि यह समाधान "अल्पविराम से अलग किए गए मान" के लिए केवल एक संभावित परिभाषा का प्रतिनिधित्व करता है।
इतिहास संपादित करें
- 2014-05-19: जोड़ा गया अस्वीकरण।
- 2014-12-01: शीर्ष पर अस्वीकरण स्थानांतरित कर दिया।