首页 > 解决方案 > 在 C# 中解析复杂的多行 CSV 文件

问题描述

我已经搜索了该站点,并找到了多个有关如何使用多种方法完成 C# 解析的示例……但在这种特定情况下没有找到可以帮助我的示例。我有一个需要解析的复杂 CSV 文件。这是一些标头数据的示例...

REPORT TITLE,New Query,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
REPORT DESCRIPTION,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
GENERATED,12/20/2019 7:33 AM ET,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Client Name,Client A,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Time Frame,Last Completed Period,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,Calendar year,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Received Date,Custom,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,01/01/2015 - 12/31/2015,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Service Date,Custom,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,01/01/2015 - 12/31/2015,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Adjustments,CHOICE(S),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,Phone Calibration,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
View,N/A,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
SERVICE LINE,Service Line Example A,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
SITE,General 1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,General 2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,General 3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,General 4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,General 5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,General 7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
FILTER,CHOICE(S),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Client ID,'00001',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,'00002',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,'00003',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,'00004',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,'00005',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,'00006',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

对于 CSV 文件的格式,我无能为力,因为它是遗留系统的一部分。放置在每行末尾的 40 个逗号以及用作行分隔符的逗号由系统放置。

到目前为止,这是我的代码所在的位置...

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualBasic.FileIO;
using System.Text.RegularExpressions;


namespace ConsoleUI
{
    class Program
    {
        static void Main(string[] args)
        {
            var sourcePath = @"L:\sourceData.csv";
            var delimiter = ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,";
            var tempPath = Path.GetTempFileName();
            var lineNumber = 0;

            var splitExpression = new Regex(@"(" + delimiter + @")(,)(?=(?:[^""]|""[^""]*"")*$)");

            using (var writer = new StreamWriter(tempPath))
            using (var reader = new StreamReader(sourcePath))

            {
                string line = null;

                while ((line = reader.ReadLine()) != null)
                {
                    lineNumber++;

                    var rows = splitExpression.Split(line).Where(s => s != delimiter).ToArray();

                    // This is where I need to place the parsed data into objects

                    writer.WriteLine(string.Join(delimiter, rows));
                }

            }
        }
    }
}

最终,我需要将每个已解析的数据移动到它自己定义的对象中。我已经建立了那个类。

在这一点上,任何可以提供的帮助都将被视为节日奇迹!谢谢你的时间。

标签: c#

解决方案


尝试以下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.csv";
        static void Main(string[] args)
        {
            StreamReader reader = new StreamReader(FILENAME);
            string line = "";
            Report report = new Report();
            string header = "";
            while ((line = reader.ReadLine()) != null)
            {
                List<string> data = new List<string>();
                string[] row = line.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToArray();
                if (row.Length > 0)
                {
                    if (line.StartsWith(","))
                    {
                        data = row.ToList();
                    }
                    else
                    {
                        header = row[0];
                        data = row.Skip(1).ToList();
                    }
                    if (data.Count == 0) continue;

                    switch (header)
                    {
                        case "REPORT TITLE":
                            report.title = data[0];
                            break;
                        case "REPORT DESCRIPTION":
                            report.description = data[0];
                            break;
                        case "GENERATED":
                            report.generated = data[0];
                            break;
                        case "Client Name":
                            report.name = data[0];
                            break;
                        case "Time Frame":
                            if (report.timeFrame == null) report.timeFrame = new List<string>();
                            report.timeFrame.AddRange(data);
                            break;
                        case "Received Date":
                            if (report.receivedDate == null) report.receivedDate = new List<string>();
                            report.receivedDate.AddRange(data);
                            break;
                        case "Service Date":
                            if (report.serviceDate == null) report.serviceDate = new List<string>();
                            report.serviceDate.AddRange(data);
                            break;
                        case "Adjustments":
                            if (report.adjustments == null) report.adjustments = new List<string>();
                            report.adjustments.AddRange(data);
                            break;
                        case "View":
                            if (report.view == null) report.view = new List<string>();
                            report.view.AddRange(data);
                            break;
                        case "SERVICE LINE":
                            if (report.serviceLine == null) report.serviceLine = new List<string>();
                            report.serviceLine.AddRange(data);
                            break;
                        case "SITE":
                            if (report.site == null) report.site = new List<string>();
                            report.site.AddRange(data);
                            break;
                        case "FILTER":
                            if (report.filter == null) report.filter = new List<string>();
                            report.filter.AddRange(data);
                            break;
                        case "Client ID":
                            if (report.clientId == null) report.clientId = new List<string>();
                            report.clientId.AddRange(data);
                            break;
                    }
                }

            }
        }
    }
    public class Report
    {
        public string title { get; set; }
        public string description { get; set; }
        public string  generated { get; set; }
        public string name { get; set; }
        public List<string> timeFrame { get; set; }
        public List<string> receivedDate { get; set; }
        public List<string> serviceDate { get; set; }
        public List<string> adjustments { get; set; }
        public List<string> view { get; set; }
        public List<string> serviceLine { get; set; }
        public List<string> site { get; set; }
        public List<string> filter { get; set; }
        public List<string> clientId { get; set; }
    }
}

推荐阅读