যার কলামগুলিতে সিএসভি বিভক্ত হবে,


105

প্রদত্ত

2,1016,7 / 31/2008 14: 22, জেফ ডালগাস, 6/5/2011 22:21, http://stackoverflow.com , "করভালিস, বা", 7679,351,81, বি 437f461b3fd27387c5d8ab47a293d35,34

উপরের তথ্যগুলিকে স্ট্রিংগুলিতে বিভক্ত করতে সি # কীভাবে ব্যবহার করবেন:

2
1016
7/31/2008 14:22
Geoff Dalgas
6/5/2011 22:21
http://stackoverflow.com
Corvallis, OR
7679
351
81
b437f461b3fd27387c5d8ab47a293d35
34

আপনি দেখতে পাচ্ছেন যে কলামগুলির মধ্যে একটিতে রয়েছে, <= (করভালিস, ওআর)

// আপডেট // সি # রেজেক্স স্প্লিটের উপর ভিত্তি করে - কোটের বাইরের কমা

string[] result = Regex.Split(samplestring, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");

1
জাভা যদিও, অনুরূপ প্রশ্ন: stackoverflow.com/questions/1757065/...
sgokhales

1
এটি করার জন্য একটি রেজেক্স ব্যবহার করা খারাপ পরামর্শ। .NET ফ্রেমওয়ার্কটি ইতিমধ্যে সিএসভি পার্স করার জন্য অন্তর্নির্মিত সমর্থন করেছে। এই উত্তরটি দেখুন যা আপনার গ্রহণ করা উচিত। অন্যথায় আমি এটিকে স্ট্যাকওভারফ্লো / সিকিউশনস / 3147836/… এর একটি রূপ হিসাবে বন্ধ করব যা ঠিক তেমনিই ভুল।
কেভ

এম্বেড থাকা কমা দিয়ে CSV ফাইলগুলি পার্স করার জন্য .NET এর অন্তর্নির্মিত সমর্থনটি কী তা দয়া করে ব্যাখ্যা করতে পারেন? আপনি কি মাইক্রোসফ্ট.ভিজুয়ালবাসিক.ফিলিও.সেক্সটফিল্ড পার্সার ক্লাসের কথা উল্লেখ করছেন?
অল সলিউশনস

উত্তর:


182

Microsoft.VisualBasic.FileIO.TextFieldParserক্লাস ব্যবহার করুন । এটি একটি সীমিত ফাইলকে পার্সিং পরিচালনা করবে TextReaderবা Streamযেখানে কিছু ক্ষেত্রগুলি উদ্ধৃতিতে আবদ্ধ রয়েছে এবং কিছু নেই।

উদাহরণ স্বরূপ:

using Microsoft.VisualBasic.FileIO;

string csv = "2,1016,7/31/2008 14:22,Geoff Dalgas,6/5/2011 22:21,http://stackoverflow.com,\"Corvallis, OR\",7679,351,81,b437f461b3fd27387c5d8ab47a293d35,34";

TextFieldParser parser = new TextFieldParser(new StringReader(csv));

// You can also read from a file
// TextFieldParser parser = new TextFieldParser("mycsvfile.csv");

parser.HasFieldsEnclosedInQuotes = true;
parser.SetDelimiters(",");

string[] fields;

while (!parser.EndOfData)
{
    fields = parser.ReadFields();
    foreach (string field in fields)
    {
        Console.WriteLine(field);
    }
} 

parser.Close();

এর ফলে নিম্নলিখিত ফলাফলের ফলাফল হওয়া উচিত:

2
1016
7/31/2008 14:22
জিওফ ডালগাস
6/5/2011 22:21
http://stackoverflow.com
করভালিস, বা
7679
351
81
b437f461b3fd27387c5d8ab47a293d35
34

আরও তথ্যের জন্য মাইক্রোসফ্ট.ভিউজুয়ালবাসিক.ফিলিও.এক্সটফিল্ড পার্সার দেখুন ।

রেফারেন্স যুক্ত Microsoft.VisualBasicকরুন। নেট ট্যাবে আপনাকে একটি রেফারেন্স যুক্ত করতে হবে ।


9
ডুড, এই সমাধানের জন্য আপনাকে অনেক ধন্যবাদ, আমার কাছে প্রায় 500K + সারি সিএসভি ডেটা রয়েছে যা আমার একটি টেবিলের মধ্যে লোড করা দরকার এবং এটিতে কোটামের ভিতরে থাকা কমা দিয়ে লোড করা হয়েছে। আমাদের পথ যদি কখনও অতিক্রম করে তবে আমি আপনার পছন্দসই একটি প্রাপ্ত বয়স্ক পানীয় beverageণী।
মার্ক ক্র্যাম

@ টিম আমি এটি ব্যবহার করেছি এবং এটি সমস্ত লাইন নম্বরগুলি এড়িয়ে যাওয়া লক্ষ্য করে, কেবলমাত্র 1050 লাইনযুক্ত একটি ফাইলের মধ্যে বিজোড় লাইন সংখ্যাগুলি প্রক্রিয়াকরণ করে। কোন ধারনা?
স্মিথ

@ স্মিথ - আপনার কোড বা নমুনা ইনপুট না দেখে আমার কোনও ধারণা নেই। আমি একটি নতুন প্রশ্ন পোস্ট করার পরামর্শ দিচ্ছি। সম্ভবত ফাইলটি ক্যারিজের রিটার্ন বা এমনকি অন্য লাইনের অন্য শেষ প্রান্তের মার্কারটি হারিয়েছে?
টিম

আমি এটি না দেখে এই লাইব্রেরি সম্পর্কে আমি জানতাম না - ধন্যবাদ! যদি অন্য কেউ যদি এমন উদাহরণ চান যা পুরো সিএসভি ফাইলকে বিশ্লেষণ করে তবে
অ্যামি ব্যারেট

2
স্ট্রিং লাগে এমন কনস্ট্রাক্টর না দেওয়ার জন্য আমরা কি মাইক্রোসফ্টকে লঞ্চ করতে পারি যাতে এটির প্রথমে একটি স্ট্রিমে রূপান্তর করার কুঁক দিয়ে উঠতে হয় ?? অন্যথায়, সুন্দর উত্তর।
লরেন পেচটেল

43

এটি অনেক দেরি হয়ে গেছে তবে এটি কারও পক্ষে সহায়ক হতে পারে। আমরা RegEx বেলো হিসাবে ব্যবহার করতে পারি।

Regex CSVParser = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
String[] Fields = CSVParser.Split(Test);

4
এটি নিখুঁত। পুরো অন্যান্য লাইব্রেরি আমদানির চেয়ে এটি ব্যবহার করুন। সাবাস।
দিজিক ইউনিড

1
ম্যাচগুলি এস্যাসিডেফ, "", " ,\" ডিএফ "হিসাবে,

এই সমাধানটি সঠিকভাবে কাজ করে না - এটি স্পিচ চিহ্নগুলির জন্য অ্যাকাউন্ট করে না, অর্থাত পঠনের সময় ভুল জায়গায় প্রচুর বক্তৃতা চিহ্ন থাকবে।
আইডানএইচ

শেষের উদ্ধৃতিটি যদি কিছু লাইনে অনুপস্থিত থাকে তবে কী হবে: এস্যাসেড, "", "হিসাবে, \" ডিএফ ","
এস্যাসেড এস্যাসেড

1
এটি আমার পক্ষে কাজ করেছে এবং উদ্ধৃত বক্তৃতা চিহ্নগুলির জন্য অ্যাকাউন্ট হয়েছে। তাদের 30 মিলিয়ন সারি। খুব ভাল এবং একটি সংখ্যক কোড।
জিবিজিওএলসি

4

আপনি সমস্ত কমাতে বিভক্ত হয়ে উঠতে পারেন যেগুলি অনুসরণ করে এমন একাধিক কোট রয়েছে।

আপনি specfকমা হ্যান্ডলিং সম্পর্কে CSV ফর্ম্যাটটিতে দেখতেও চাই ।

দরকারী লিঙ্ক: C# Regex Split - commas outside quotes


3
@ q0987 - এটি সঠিক উত্তর নয়। ফ্রেমওয়ার্কে এটির
কেভ

4

আমি দেখতে পাচ্ছি যে আপনি যদি এক্সেলে সিএসভির সীমাবদ্ধ পাঠ্যটি পেস্ট করেন এবং একটি "টেক্সট টু কলাম" করেন, এটি আপনাকে একটি "পাঠ্য বাছাইকারী" জিজ্ঞাসা করবে। এটি একটি ডাবল উদ্ধৃতিতে ডিফল্ট হয়েছে যাতে এটি পাঠ্যকে আক্ষরিক হিসাবে বিবেচনা করে ral আমি কল্পনা করি যে এক্সেল একবারে একটি চরিত্রের মাধ্যমে এটি প্রয়োগ করে, যদি এটি একটি "পাঠ্য বাছাইকারী" এর সাথে মুখোমুখি হয়, তবে এটি পরবর্তী "বাছাইকারী" এ যেতে থাকবে। আপনি যদি আক্ষরিক পাঠ্যের অভ্যন্তরে থাকেন তবে আপনি সম্ভবত এটি লুপ এবং একটি বুলিয়ান দ্বারা এটি প্রয়োগ করতে পারেন।

public string[] CsvParser(string csvText)
{
    List<string> tokens = new List<string>();

    int last = -1;
    int current = 0;
    bool inText = false;

    while(current < csvText.Length)
    {
        switch(csvText[current])
        {
            case '"':
                inText = !inText; break;
            case ',':
                if (!inText) 
                {
                    tokens.Add(csvText.Substring(last + 1, (current - last)).Trim(' ', ',')); 
                    last = current;
                }
                break;
            default:
                break;
        }
        current++;
    }

    if (last != csvText.Length - 1) 
    {
        tokens.Add(csvText.Substring(last+1).Trim());
    }

    return tokens.ToArray();
}

3

আপনার সিএসভি পড়ার জন্য লুমেন ওয়ার্কসের মতো একটি লাইব্রেরি ব্যবহার করুন । এটি ক্ষেত্রগুলিতে সেগুলিকে উদ্ধৃতি সহ পরিচালনা করবে এবং দীর্ঘকাল ধরে থাকার কারণে আপনার কাস্টম সমাধানের চেয়ে সামগ্রিকভাবে আরও শক্তিশালী হবে।


2

.Csv ফাইলগুলি পার্স করা জটিল বিষয়, যখন .csv ফাইলটি কমা দ্বারা পৃথক করা স্ট্রিং, কমা দ্বারা পৃথককৃত উদ্ধৃত স্ট্রিং বা দুটির বিশৃঙ্খল সমন্বয় হতে পারে। আমি যে সমাধানটি নিয়ে এসেছি তা তিনটি সম্ভাবনার যে কোনওটির জন্য মঞ্জুরি দেয়।

আমি একটি পদ্ধতি তৈরি করেছি, পার্সেসিএসভিআরও () যা সিএসভি স্ট্রিং থেকে অ্যারে প্রদান করে। আমি প্রথমে স্ট্রিংয়ে ডাবল কোট নিয়ে ডাবল কোটায় স্ট্রিটকে quotes অ্যারে নামক অ্যারেতে বিভক্ত করে ডিল করি। উদ্ধৃত স্ট্রিং .csv ফাইলগুলি কেবলমাত্র বৈধ তবেই যদি ডাবল কোটগুলির একটি সংখ্যক সংখ্যা থাকে। একটি কলামের মানে ডাবল উদ্ধৃতিগুলি এক জোড়া ডাবল কোটের সাথে প্রতিস্থাপন করা উচিত (এটি এক্সেলের দৃষ্টিভঙ্গি)। যতক্ষণ না .csv ফাইলটি এই প্রয়োজনীয়তাগুলি পূরণ করে, আপনি ডিলিমিটার কমাগুলি কেবল জোড়া জোড়ের বাইরে উপস্থিত হওয়ার আশা করতে পারেন। জোড়া জোড়া ডাবল কোটের ভিতরে থাকা কমাগুলি কলাম মানটির অংশ এবং .csv কে অ্যারেতে বিভক্ত করার সময় এড়ানো উচিত।

আমার পদ্ধতিটি ডাবল উদ্ধৃতি জোড়ের বাইরে কমাগুলির পরীক্ষার জন্য কেবল উদ্ধৃতি অ্যারির সমান সূচকগুলি দেখে। এটি কলাম মানগুলির শুরু এবং শেষ থেকে ডাবল উদ্ধৃতিগুলি সরিয়ে দেয়।

    public static string[] ParseCsvRow(string csvrow)
    {
        const string obscureCharacter = "ᖳ";
        if (csvrow.Contains(obscureCharacter)) throw new Exception("Error: csv row may not contain the " + obscureCharacter + " character");

        var unicodeSeparatedString = "";

        var quotesArray = csvrow.Split('"');  // Split string on double quote character
        if (quotesArray.Length > 1)
        {
            for (var i = 0; i < quotesArray.Length; i++)
            {
                // CSV must use double quotes to represent a quote inside a quoted cell
                // Quotes must be paired up
                // Test if a comma lays outside a pair of quotes.  If so, replace the comma with an obscure unicode character
                if (Math.Round(Math.Round((decimal) i/2)*2) == i)
                {
                    var s = quotesArray[i].Trim();
                    switch (s)
                    {
                        case ",":
                            quotesArray[i] = obscureCharacter;  // Change quoted comma seperated string to quoted "obscure character" seperated string
                            break;
                    }
                }
                // Build string and Replace quotes where quotes were expected.
                unicodeSeparatedString += (i > 0 ? "\"" : "") + quotesArray[i].Trim();
            }
        }
        else
        {
            // String does not have any pairs of double quotes.  It should be safe to just replace the commas with the obscure character
            unicodeSeparatedString = csvrow.Replace(",", obscureCharacter);
        }

        var csvRowArray = unicodeSeparatedString.Split(obscureCharacter[0]); 

        for (var i = 0; i < csvRowArray.Length; i++)
        {
            var s = csvRowArray[i].Trim();
            if (s.StartsWith("\"") && s.EndsWith("\""))
            {
                csvRowArray[i] = s.Length > 2 ? s.Substring(1, s.Length - 2) : "";  // Remove start and end quotes.
            }
        }

        return csvRowArray;
    }

আমার পদ্ধতির একটি খারাপ দিক হ'ল আমি সাময়িকভাবে অস্পষ্ট ইউনিকোড চরিত্রের সাথে ডিলিমিটার কমাগুলি প্রতিস্থাপন করি। এই চরিত্রটি এতটাই অস্পষ্ট হওয়া দরকার, এটি কখন আপনার .csv ফাইলে প্রদর্শিত হবে না। আপনি এটিকে আরও পরিচালনা করতে চাইতে পারেন।


1

আমার একটি সিএসভি নিয়ে সমস্যা ছিল যার মধ্যে একটি উদ্ধৃতি চরিত্র সহ ক্ষেত্র রয়েছে, সুতরাং টেক্সটফিল্ড পার্সার ব্যবহার করে আমি নিম্নলিখিতটি উপস্থিত করেছি:

private static string[] parseCSVLine(string csvLine)
{
  using (TextFieldParser TFP = new TextFieldParser(new MemoryStream(Encoding.UTF8.GetBytes(csvLine))))
  {
    TFP.HasFieldsEnclosedInQuotes = true;
    TFP.SetDelimiters(",");

    try 
    {           
      return TFP.ReadFields();
    }
    catch (MalformedLineException)
    {
      StringBuilder m_sbLine = new StringBuilder();

      for (int i = 0; i < TFP.ErrorLine.Length; i++)
      {
        if (i > 0 && TFP.ErrorLine[i]== '"' &&(TFP.ErrorLine[i + 1] != ',' && TFP.ErrorLine[i - 1] != ','))
          m_sbLine.Append("\"\"");
        else
          m_sbLine.Append(TFP.ErrorLine[i]);
      }

      return parseCSVLine(m_sbLine.ToString());
    }
  }
}

স্ট্রিমরেডারটি এখনও সিএসভি লাইনটি লাইন দ্বারা পড়তে ব্যবহৃত হয়:

using(StreamReader SR = new StreamReader(FileName))
{
  while (SR.Peek() >-1)
    myStringArray = parseCSVLine(SR.ReadLine());
}

1

সঙ্গে Cinchoo সংক্ষিপ্তসার ETL - একটি ওপেন সোর্স লাইব্রেরি, এটি স্বয়ংক্রিয়ভাবে হ্যান্ডলগুলি কলাম মান বিভাজক ধারণকারী পারবেন না।

string csv = @"2,1016,7/31/2008 14:22,Geoff Dalgas,6/5/2011 22:21,http://stackoverflow.com,""Corvallis, OR"",7679,351,81,b437f461b3fd27387c5d8ab47a293d35,34";

using (var p = ChoCSVReader.LoadText(csv)
    )
{
    Console.WriteLine(p.Dump());
}

আউটপুট:

Key: Column1 [Type: String]
Value: 2
Key: Column2 [Type: String]
Value: 1016
Key: Column3 [Type: String]
Value: 7/31/2008 14:22
Key: Column4 [Type: String]
Value: Geoff Dalgas
Key: Column5 [Type: String]
Value: 6/5/2011 22:21
Key: Column6 [Type: String]
Value: http://stackoverflow.com
Key: Column7 [Type: String]
Value: Corvallis, OR
Key: Column8 [Type: String]
Value: 7679
Key: Column9 [Type: String]
Value: 351
Key: Column10 [Type: String]
Value: 81
Key: Column11 [Type: String]
Value: b437f461b3fd27387c5d8ab47a293d35
Key: Column12 [Type: String]
Value: 34

আরও তথ্যের জন্য, দয়া করে কোডপোজেক্ট নিবন্ধটি দেখুন।

আশা করি এটা সাহায্য করবে.

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.