दिलचस्प पोस्ट
एन्जोर 2 में एनजी के लिए जेसन ऑब्जेक्ट को पुनरावृत्ति करना आईओएस: डिवाइस वॉल्यूम बदलें पृष्ठ लोड हो रहा है, जबकि एक चलती प्रगति बार कैसे दिखाएं आईओएस 8 सिम्युलेटर बूट करने में असमर्थ उपयोगकर्ता इनपुट को इनपुट फ़ील्ड में दर्ज करते समय कैसे पता लगाया जाए सी ++ में एक बेस के अतिभारित फ़ंक्शन को ओवरराइड करना सी # में अपवाद को अनदेखा करें वर्तमान कार्य निर्देशिका को सी ++ में बदलें मैं ज्येथोन में विभिन्न पायथन लाइब्रेरी कैसे स्थापित कर सकता हूं? Preg_replace का उपयोग कर PHP: "डेलीमीटर को अल्फ़ान्यूमेरिक या बैकस्लैश नहीं होना चाहिए" त्रुटि जावा में डुप्लिकेट एचटीएमएल टैग को कैसे हटाएं? default_url_options और रेल 3 जावा अनुप्रयोग में अनुकूलन शॉर्टकट आप एक मैट्रिक्स की पंक्तियों को सदिश में कैसे जोड़ते हैं? सी ++ 11 के पीओडी "मानक लेआउट" की परिभाषा किस तरह से है?

उद्धृत और अनक्ोटेड स्ट्रिंग दोनों के साथ अल्पविराम से अलग स्ट्रिंग विभाजित करें

मेरे पास निम्न अल्पविराम से अलग स्ट्रिंग है जिसे मुझे विभाजित करने की आवश्यकता है I समस्या ये है कि सामग्री में से कुछ उद्धरण चिह्नों के भीतर है और इसमें ऐसे अल्पविराम शामिल हैं जिनका उपयोग विभाजन में नहीं किया जाना चाहिए …

स्ट्रिंग:

111,222,"33,44,55",666,"77,88","99" 

मुझे आउटपुट चाहिए:

 111 222 33,44,55 666 77,88 99 

मैंने यह कोशिश की है:

 (?:,?)((?<=")[^"]+(?=")|[^",]+) 

लेकिन यह "77,88", "99" हिट के रूप में कॉमा को पढ़ता है और मुझे निम्न आउटपुट मिलता है:

 111 222 33,44,55 666 77,88 , 99 

कोई भी मेरी मदद कर सकता हैं? मैं घंटों से बाहर चल रहा हूं … 🙂 / पीटर

Solutions Collecting From Web of "उद्धृत और अनक्ोटेड स्ट्रिंग दोनों के साथ अल्पविराम से अलग स्ट्रिंग विभाजित करें"

अपनी आवश्यकताओं के आधार पर आप एक सीएसवी पार्सर का उपयोग करने में सक्षम नहीं हो सकते हैं, और वास्तव में पहिया का पुन: आविष्कार करना चाहते हैं !!

आप ऐसा कुछ सरल regex के साथ कर सकते हैं

 (?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*) 

यह निम्न कार्य करेगा:

(?:^|,) = मैच स्ट्रिंग की शुरुआत "लाइन या स्ट्रिंग"

(\"(?:[^\"]+|\"\")*\"|[^,]*) = एक गिने हुए कैप्चर समूह, यह 2 विकल्पों के बीच चयन करेगा:

  1. उद्धरण में सामान
  2. अल्पविराम के बीच सामान

इससे आपको उस आउटपुट को देना चाहिए जो आप देख रहे हैं।

सी # में उदाहरण कोड

 public static string[] SplitCSV(string input) { Regex csvSplit = new Regex("(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)", RegexOptions.Compiled); List<string> list = new List<string>(); string curr = null; foreach (Match match in csvSplit.Matches(input)) { curr = match.Value; if (0 == curr.Length) { list.Add(""); } list.Add(curr.TrimStart(',')); } return list.ToArray<string>(); } private void button1_Click(object sender, RoutedEventArgs e) { Console.WriteLine(SplitCSV("111,222,\"33,44,55\",666,\"77,88\",\"99\"")); } 

मुझे वास्तव में जम्प्लोड के उत्तर पसंद है, लेकिन मुझे लगता है कि उपज रिटर्न के साथ एक संस्करण थोड़ी अधिक उपयोगी है, इसलिए यहां यह है:

 public IEnumerable<string> SplitCSV(string input) { Regex csvSplit = new Regex("(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)", RegexOptions.Compiled); foreach (Match match in csvSplit.Matches(input)) { yield return match.Value.TrimStart(','); } } 

हो सकता है कि यह एक एक्सटेंशन विधि की तरह अधिक उपयोगी हो:

 public static class StringHelper { public static IEnumerable<string> SplitCSV(this string input) { Regex csvSplit = new Regex("(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)", RegexOptions.Compiled); foreach (Match match in csvSplit.Matches(input)) { yield return match.Value.TrimStart(','); } } } 

सीएसवी पार्सर को फिर से न लगाएँ , फाइलहेल्पर का प्रयास करें

यह नियमित रूप से अभिव्यक्ति मूल्यों और TrimStart(',') माध्यम से लूप की आवश्यकता के बिना काम करती है, जैसे स्वीकार्य उत्तर में:

 ((?<=\")[^\"]*(?=\"(,|$)+)|(?<=,|^)[^,\"]*(?=,|$)) 

सी # में कार्यान्वयन है:

 string values = "111,222,\"33,44,55\",666,\"77,88\",\"99\""; MatchCollection matches = new Regex("((?<=\")[^\"]*(?=\"(,|$)+)|(?<=,|^)[^,\"]*(?=,|$))").Matches(values); foreach (var match in matches) { Console.WriteLine(match); } 

आउटपुट

 111 222 33,44,55 666 77,88 99 

इसे इस्तेमाल करे:

  string s = @"111,222,""33,44,55"",666,""77,88"",""99"""; List<string> result = new List<string>(); var splitted = s.Split('"').ToList<string>(); splitted.RemoveAll(x => x == ","); foreach (var it in splitted) { if (it.StartsWith(",") || it.EndsWith(",")) { var tmp = it.TrimEnd(',').TrimStart(','); result.AddRange(tmp.Split(',')); } else { if(!string.IsNullOrEmpty(it)) result.Add(it); } } //Results: foreach (var it in result) { Console.WriteLine(it); } 

जे के उत्तर के लिए, यदि आप 2 बूलियन का उपयोग करते हैं, तो आप सिंगल-कोट्स और उपाध्यक्ष के विपरीत डबल-उद्धरण रख सकते हैं।

  private string[] splitString(string stringToSplit) { char[] characters = stringToSplit.ToCharArray(); List<string> returnValueList = new List<string>(); string tempString = ""; bool blockUntilEndQuote = false; bool blockUntilEndQuote2 = false; int characterCount = 0; foreach (char character in characters) { characterCount = characterCount + 1; if (character == '"' && !blockUntilEndQuote2) { if (blockUntilEndQuote == false) { blockUntilEndQuote = true; } else if (blockUntilEndQuote == true) { blockUntilEndQuote = false; } } if (character == '\'' && !blockUntilEndQuote) { if (blockUntilEndQuote2 == false) { blockUntilEndQuote2 = true; } else if (blockUntilEndQuote2 == true) { blockUntilEndQuote2 = false; } } if (character != ',') { tempString = tempString + character; } else if (character == ',' && (blockUntilEndQuote == true || blockUntilEndQuote2 == true)) { tempString = tempString + character; } else { returnValueList.Add(tempString); tempString = ""; } if (characterCount == characters.Length) { returnValueList.Add(tempString); tempString = ""; } } string[] returnValue = returnValueList.ToArray(); return returnValue; } 

मुझे पता है कि मैं थोड़ा देर कर रहा हूं, लेकिन खोजों के लिए, यहां बताया गया है कि आपने सी के बारे में क्या कहा है

 private string[] splitString(string stringToSplit) { char[] characters = stringToSplit.ToCharArray(); List<string> returnValueList = new List<string>(); string tempString = ""; bool blockUntilEndQuote = false; int characterCount = 0; foreach (char character in characters) { characterCount = characterCount + 1; if (character == '"') { if (blockUntilEndQuote == false) { blockUntilEndQuote = true; } else if (blockUntilEndQuote == true) { blockUntilEndQuote = false; } } if (character != ',') { tempString = tempString + character; } else if (character == ',' && blockUntilEndQuote == true) { tempString = tempString + character; } else { returnValueList.Add(tempString); tempString = ""; } if (characterCount == characters.Length) { returnValueList.Add(tempString); tempString = ""; } } string[] returnValue = returnValueList.ToArray(); return returnValue; } 

"जवाब "value, 1" रूप में "value, 1" , या डबल-उद्धरणों से बचकर स्ट्रिंग के भीतर उद्धरण चिह्नों के अंदर कोई अल्पविराम है, जो इन उत्तरों में से कोई भी कार्य नहीं करता है, जो कि मान्य सीएसवी है जिसे value, 1 रूप में पार्स किया जाना चाहिए value, 1 और value "1" , क्रमशः।

यह टैब-सीमांकित प्रारूप के साथ भी काम करेगा यदि आप अपने सीमांकक के रूप में किसी अल्पविराम के बजाय किसी टैब में पास करते हैं

 public static IEnumerable<string> SplitRow(string row, char delimiter = ',') { var currentString = new StringBuilder(); var inQuotes = false; var quoteIsEscaped = false; //Store when a quote has been escaped. row = string.Format("{0}{1}", row, delimiter); //We add new cells at the delimiter, so append one for the parser. foreach (var character in row.Select((val, index) => new {val, index})) { if (character.val == delimiter) //We hit a delimiter character... { if (!inQuotes) //Are we inside quotes? If not, we've hit the end of a cell value. { Console.WriteLine(currentString); yield return currentString.ToString(); currentString.Clear(); } else { currentString.Append(character.val); } } else { if (character.val != ' ') { if(character.val == '"') //If we've hit a quote character... { if(character.val == '\"' && inQuotes) //Does it appear to be a closing quote? { if (row[character.index + 1] == character.val) //If the character afterwards is also a quote, this is to escape that (not a closing quote). { quoteIsEscaped = true; //Flag that we are escaped for the next character. Don't add the escaping quote. } else if (quoteIsEscaped) { quoteIsEscaped = false; //This is an escaped quote. Add it and revert quoteIsEscaped to false. currentString.Append(character.val); } else { inQuotes = false; } } else { if (!inQuotes) { inQuotes = true; } else { currentString.Append(character.val); //...It's a quote inside a quote. } } } else { currentString.Append(character.val); } } else { if (!string.IsNullOrWhiteSpace(currentString.ToString())) //Append only if not new cell { currentString.Append(character.val); } } } } } 

"चाड हेडकोकॉक" द्वारा प्रदान किए गए फ़ंक्शन के मामूली अपडेट के साथ

अपडेट चालू हैं:

रेखा 26: चरित्र.वल == '\ "' – रेखा 24 पर किए गए चेक के कारण यह कभी भी सच नहीं हो सकता है। अर्थात चरित्र.वल == '' ''

रेखा 28: यदि (पंक्ति {character.index + 1] == character.val) जोड़ा गया! उद्धरण आई 3 से लगातार उद्धरण से बचने के लिए बच गया

 public static IEnumerable<string> SplitRow(string row, char delimiter = ',') { var currentString = new StringBuilder(); var inQuotes = false; var quoteIsEscaped = false; //Store when a quote has been escaped. row = string.Format("{0}{1}", row, delimiter); //We add new cells at the delimiter, so append one for the parser. foreach (var character in row.Select((val, index) => new {val, index})) { if (character.val == delimiter) //We hit a delimiter character... { if (!inQuotes) //Are we inside quotes? If not, we've hit the end of a cell value. { //Console.WriteLine(currentString); yield return currentString.ToString(); currentString.Clear(); } else { currentString.Append(character.val); } } else { if (character.val != ' ') { if(character.val == '"') //If we've hit a quote character... { if(character.val == '"' && inQuotes) //Does it appear to be a closing quote? { if (row[character.index + 1] == character.val && !quoteIsEscaped) //If the character afterwards is also a quote, this is to escape that (not a closing quote). { quoteIsEscaped = true; //Flag that we are escaped for the next character. Don't add the escaping quote. } else if (quoteIsEscaped) { quoteIsEscaped = false; //This is an escaped quote. Add it and revert quoteIsEscaped to false. currentString.Append(character.val); } else { inQuotes = false; } } else { if (!inQuotes) { inQuotes = true; } else { currentString.Append(character.val); //...It's a quote inside a quote. } } } else { currentString.Append(character.val); } } else { if (!string.IsNullOrWhiteSpace(currentString.ToString())) //Append only if not new cell { currentString.Append(character.val); } } } } 

}

वर्तमान में मैं निम्नलिखित regex का उपयोग करता हूँ:

  public static Regex regexCSVSplit = new Regex(@"(?x:( (?<FULL> (^|[,;\t\r\n])\s* ( (?<CODAT> (?<CO>[""'])(?<DAT>([^,;\t\r\n]|(?<!\k<CO>\s*)[,;\t\r\n])*)\k<CO>) | (?<CODAT> (?<DAT> [^""',;\s\r\n]* )) ) (?=\s*([,;\t\r\n]|$)) ) | (?<FULL> (^|[\s\t\r\n]) ( (?<CODAT> (?<CO>[""'])(?<DAT> [^""',;\s\t\r\n]* )\k<CO>) | (?<CODAT> (?<DAT> [^""',;\s\t\r\n]* )) ) (?=[,;\s\t\r\n]|$)) ))", RegexOptions.Compiled); 

यह समाधान नीचे की तरह बहुत अराजक मामलों को भी संभाल सकता है: यहां छवि विवरण दर्ज करें

इस परिणाम को एक सरणी में कैसे फ़ीड करना है:

  var data = regexCSVSplit.Matches(line_to_process).Cast<Match>().Select(x => x.Groups["DAT"].Value).ToArray(); 

कार्रवाई में यह उदाहरण यहां देखें

मुझे एक बार ऐसा कुछ करना था और अंत में मुझे नियमित अभिव्यक्तियों के साथ अटक गया था। Regex के लिए राज्य होने की अक्षमता यह बहुत मुश्किल बना देता है – मैं बस एक सरल सा पार्सर लिख रहा हूं

यदि आप सीएसवी पार्सिंग कर रहे हैं तो आपको केवल सीएसवी पार्सर का इस्तेमाल करना चाहिए – पहिया को फिर से नहीं लगाएं

स्ट्रिंग कच्चे पॉइंटर हेरफेर के आधार पर यहां मेरा सबसे तेज़ कार्यान्वयन है:

 string[] FastSplit(string sText, char? cSeparator = null, char? cQuotes = null) { string[] oTokens; if (null == cSeparator) { cSeparator = DEFAULT_PARSEFIELDS_SEPARATOR; } if (null == cQuotes) { cQuotes = DEFAULT_PARSEFIELDS_QUOTE; } unsafe { fixed (char* lpText = sText) { #region Fast array estimatation char* lpCurrent = lpText; int nEstimatedSize = 0; while (0 != *lpCurrent) { if (cSeparator == *lpCurrent) { nEstimatedSize++; } lpCurrent++; } nEstimatedSize++; // Add EOL char(s) string[] oEstimatedTokens = new string[nEstimatedSize]; #endregion #region Parsing char[] oBuffer = new char[sText.Length]; int nIndex = 0; int nTokens = 0; lpCurrent = lpText; while (0 != *lpCurrent) { if (cQuotes == *lpCurrent) { // Quotes parsing lpCurrent++; // Skip quote nIndex = 0; // Reset buffer while ( (0 != *lpCurrent) && (cQuotes != *lpCurrent) ) { oBuffer[nIndex] = *lpCurrent; // Store char lpCurrent++; // Move source cursor nIndex++; // Move target cursor } } else if (cSeparator == *lpCurrent) { // Separator char parsing oEstimatedTokens[nTokens++] = new string(oBuffer, 0, nIndex); // Store token nIndex = 0; // Skip separator and Reset buffer } else { // Content parsing oBuffer[nIndex] = *lpCurrent; // Store char nIndex++; // Move target cursor } lpCurrent++; // Move source cursor } // Recover pending buffer if (nIndex > 0) { // Store token oEstimatedTokens[nTokens++] = new string(oBuffer, 0, nIndex); } // Build final tokens list if (nTokens == nEstimatedSize) { oTokens = oEstimatedTokens; } else { oTokens = new string[nTokens]; Array.Copy(oEstimatedTokens, 0, oTokens, 0, nTokens); } #endregion } } // Epilogue return oTokens; } 

मुझे थोड़ी अधिक मजबूत जरूरत थी, इसलिए मैंने यहां से लिया और इसे बनाया … यह समाधान थोड़ा कम सुरुचिपूर्ण और थोड़ा और अधिक है, लेकिन मेरे परीक्षण में (1,000,000 पंक्ति नमूनों के साथ), मुझे यह 2 होना चाहिए 3 गुना तेजी से प्लस यह गैर बच, एम्बेडेड उद्धरण संभालता है। मेरे समाधान की आवश्यकताओं की वजह से मैंने स्टैन्ड सीमांकक और पात्रों के बजाय वर्ण का उपयोग किया। मुझे एक अच्छा, सामान्य सीएसवी पार्सर खोजने की अपेक्षा की तुलना में मैं इसे और अधिक कठिन पाया, इसलिए मुझे उम्मीद है कि यह पार्सिंग एल्गोरिथ्म किसी को मदद कर सकता है।

  public static string[] SplitRow(string record, string delimiter, string qualifier, bool trimData) { // In-Line for example, but I implemented as string extender in production code Func <string, int, int> IndexOfNextNonWhiteSpaceChar = delegate (string source, int startIndex) { if (startIndex >= 0) { if (source != null) { for (int i = startIndex; i < source.Length; i++) { if (!char.IsWhiteSpace(source[i])) { return i; } } } } return -1; }; var results = new List<string>(); var result = new StringBuilder(); var inQualifier = false; var inField = false; // We add new columns at the delimiter, so append one for the parser. var row = $"{record}{delimiter}"; for (var idx = 0; idx < row.Length; idx++) { // A delimiter character... if (row[idx]== delimiter[0]) { // Are we inside qualifier? If not, we've hit the end of a column value. if (!inQualifier) { results.Add(trimData ? result.ToString().Trim() : result.ToString()); result.Clear(); inField = false; } else { result.Append(row[idx]); } } // NOT a delimiter character... else { // ...Not a space character if (row[idx] != ' ') { // A qualifier character... if (row[idx] == qualifier[0]) { // Qualifier is closing qualifier... if (inQualifier && row[IndexOfNextNonWhiteSpaceChar(row, idx + 1)] == delimiter[0]) { inQualifier = false; continue; } else { // ...Qualifier is opening qualifier if (!inQualifier) { inQualifier = true; } // ...It's a qualifier inside a qualifier. else { inField = true; result.Append(row[idx]); } } } // Not a qualifier character... else { result.Append(row[idx]); inField = true; } } // ...A space character else { if (inQualifier || inField) { result.Append(row[idx]); } } } } return results.ToArray<string>(); } 

कुछ परीक्षण कोड:

  //var input = "111,222,\"33,44,55\",666,\"77,88\",\"99\""; var input = "111, 222, \"99\",\"33,44,55\" , \"666 \"mark of a man\"\", \" spaces \"77,88\" \""; Console.WriteLine("Split with trim"); Console.WriteLine("---------------"); var result = SplitRow(input, ",", "\"", true); foreach (var r in result) { Console.WriteLine(r); } Console.WriteLine(""); // Split 2 Console.WriteLine("Split with no trim"); Console.WriteLine("------------------"); var result2 = SplitRow(input, ",", "\"", false); foreach (var r in result2) { Console.WriteLine(r); } Console.WriteLine(""); // Time Trial 1 Console.WriteLine("Experimental Process (1,000,000) iterations"); Console.WriteLine("-------------------------------------------"); watch = Stopwatch.StartNew(); for (var i = 0; i < 1000000; i++) { var x1 = SplitRow(input, ",", "\"", false); } watch.Stop(); elapsedMs = watch.ElapsedMilliseconds; Console.WriteLine($"Total Process Time: {string.Format("{0:0.###}", elapsedMs / 1000.0)} Seconds"); Console.WriteLine(""); 

परिणाम

 Split with trim --------------- 111 222 99 33,44,55 666 "mark of a man" spaces "77,88" Split with no trim ------------------ 111 222 99 33,44,55 666 "mark of a man" spaces "77,88" Original Process (1,000,000) iterations ------------------------------- Total Process Time: 7.538 Seconds Experimental Process (1,000,000) iterations -------------------------------------------- Total Process Time: 3.363 Seconds 

इसे इस्तेमाल करे

 private string[] GetCommaSeperatedWords(string sep, string line) { List<string> list = new List<string>(); StringBuilder word = new StringBuilder(); int doubleQuoteCount = 0; for (int i = 0; i < line.Length; i++) { string chr = line[i].ToString(); if (chr == "\"") { if (doubleQuoteCount == 0) doubleQuoteCount++; else doubleQuoteCount--; continue; } if (chr == sep && doubleQuoteCount == 0) { list.Add(word.ToString()); word = new StringBuilder(); continue; } word.Append(chr); } list.Add(word.ToString()); return list.ToArray(); }