Asked  7 Months ago    Answers:  5   Viewed   215 times

Given

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

How to use C# to split the above information into strings as follows:

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

As you can see one of the column contains , <= (Corvallis, OR)

update

Based on C# Regex Split - commas outside quotes

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

 Answers

46

Use the Microsoft.VisualBasic.FileIO.TextFieldParser class. This will handle parsing a delimited file, TextReader or Stream where some fields are enclosed in quotes and some are not.

For example:

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();

This should result in the following output:

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

See Microsoft.VisualBasic.FileIO.TextFieldParser for more information.

You need to add a reference to Microsoft.VisualBasic in the Add References .NET tab.

Tuesday, June 1, 2021
 
Gordnfreeman
answered 7 Months ago
56

I was able to get this to work by adding a DataTable row and filling it in explicitly, instead of trying to add a CsvHelper record as a row.

I used the following part instead of the similar part that is shown above:

foreach (var record in records)
{
    DataRow row = dt.NewRow();
    record.CompanyId = company.Id;
    row["Date"] = record.Date;
    row["Close"] = record.Close;
    row["AdjClose"] = record.AdjClose;
    row["High"] = record.High;
    row["Low"] = record.Low;
    row["Open"] = record.Open;
    row["Volume"] = record.Volume;
    row["CompanyId"] = record.CompanyId;
    dt.Rows.Add(row);
}

If you can solve the issue without so much hard coding, I will accept your answer as the answer.

Thursday, August 12, 2021
 
MikeMcClatchie
answered 4 Months ago
59

Are you doing this at work? Is a corporate firewall or anti-virus program running? Check the windows event logs and any applications in your task notification icons area on your start bar for hints as to who is blocking this.

Wednesday, August 25, 2021
 
panthro
answered 4 Months ago
83

If you're doing this parsing as a learning exercise, that's fine. However, CPAN has several modules that will do a lot of the work for you.

use Config::Simple;
Config::Simple->import_from( 'some_config_file.txt', my %conf );
Saturday, October 30, 2021
 
ead
answered 1 Month ago
ead
15

@dimmits answer works just fine and is easy to read. I thought I would provide another option that is more configuration based. It does require a modification to the StudentInfo class.

public class Program
{
    public static void Main(string[] args)
    {
        var studentInfos = FetchStudentInfo();

        using (var csv = new CsvWriter(Console.Out))
        {
            csv.Configuration.HasHeaderRecord = false;
            csv.Configuration.RegisterClassMap<StudentInfoMap>();

            csv.WriteRecords(studentInfos);
        }

        Console.ReadKey();
    }

    public static List<StudentInfo> FetchStudentInfo()
    {
        Course[] courses1 = { new Course { CourseId = "1", CourseName = "java" }, new Course { CourseId = "2", CourseName = "c#" }, new Course { CourseId = "3", CourseName = "python" } };
        Course[] courses2 = { new Course { CourseId = "1", CourseName = "java" }, new Course { CourseId = "2", CourseName = "c#" } };
        return new List<StudentInfo>
        {
            new StudentInfo{ Student = new Student{Id = "12", Name = "Jim"}, Courses = courses1 },
            new StudentInfo{ Student = new Student{Id = "45", Name = "Dave"}, Courses = courses2 }
        };
    }
}

public class StudentInfoMap : ClassMap<StudentInfo>
{
    public StudentInfoMap()
    {
        References<StudentMap>(m => m.Student);
        Map(m => m.CourseNames).Index(3);
    }
}

public class StudentMap : ClassMap<Student>
{
    public StudentMap()
    {
        Map(m => m.Id);
        Map(m => m.Name);
    }
}

public class StudentInfo
{
    public Student Student { get; set; }
    public Course[] Courses { get; set; }
    public string[] CourseNames { get { return Courses.Select(c => c.CourseName).ToArray(); } }
}

public class Student
{
    public string Id { get; set; }
    public string Name { get; set; }
}

public class Course
{
    public string CourseId { get; set; }
    public string CourseName { get; set; }
}
Wednesday, December 1, 2021
 
Octopus
answered 1 Week ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share