【问题标题】:Don't split the string if contains in double marks如果包含在双标记中,则不要拆分字符串
【发布时间】:2015-06-04 10:20:10
【问题描述】:

我有一个文本分隔文件需要转换成数据表。给定这样的文字:

Name,Contact,Email,Date Of Birth,Address
JOHN,01212121,hehe@yahoo.com,1/12/1987,"mawar rd, shah alam, selangor"
JACKSON,01223323,haha@yahoo.com,1/4/1967,"neelofa rd, sepang, selangor"
DAVID,0151212,hoho@yahoo.com,3/5/1956,"nora danish rd, klang, selangor"

这就是我在 C# 中读取文本文件的方式

DataTable table = new DataTable();                

                    using (StreamReader sr = new StreamReader(path))
                    {
                        #region Text to csv
                        while (!sr.EndOfStream)
                        {
                            string[] line = sr.ReadLine().Split(',');
                            //table.Rows.Add(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5]);

                            if (IsRowHeader)//Is user want to read first row as the header
                            {
                                foreach (string column in line)
                                {
                                    table.Columns.Add(column);
                                }

                                totalColumn = line.Count();

                                IsRowHeader = false;
                            }
                            else
                            {
                                if (totalColumn == 0)
                                {
                                    totalColumn = line.Count();

                                    for (int j = 0; j < totalColumn; j++)
                                    {
                                        table.Columns.Add();
                                    }

                                }

                                // create a DataRow using .NewRow()
                                DataRow row = table.NewRow();

                                // iterate over all columns to fill the row
                                for (int i = 0; i < line.Count(); i++)
                                {
                                    row[i] = line[i];
                                }

                                // add the current row to the DataTable
                                table.Rows.Add(row);
                            }          
                        }

列是动态的,用户可以在文本文件中添加或删除列。所以我需要检查有多少列并设置为数据表,然后我将读取每一行,将值设置为数据行,然后将行添加到表中。

如果我不删除双标记内的分号,则会显示错误“找不到第 5 列”,因为第一行只有 4 列(从 0 开始)。

处理文本分隔的最佳方法是什么?

【问题讨论】:

标签: c# datatable


【解决方案1】:

不要尝试重新发明 CSV 解析轮。使用 .NET 内置的解析器:Microsoft.VisualBasic.FileIO.TextFieldParser

https://stackoverflow.com/a/3508572/7122

【讨论】:

  • 为什么这被否决了?对我来说似乎是一个非常好的答案。 +1
  • @amcdermott。我认为它被否决了,因为我误解了这个问题,但我想我没有。
【解决方案2】:

不,只是不要。不要尝试编写自己的 CSV 解析器 - 没有理由这样做。

This article 解释了问题并建议使用FileHelpers - 这已经足够了。

还有Lumenworks reader,它更简单也同样有用。

最后显然您可以使用 DataSets 链接到您的 CSV as described here。我没有尝试过这个,但看起来很有趣,如果可能已经过时了。

【讨论】:

    【解决方案3】:

    我通常会这样:

    const char separator = ',';
    using (var reader = new StreamReader("C:\\sample.txt"))
    {
    
        var fields = (reader.ReadLine() ?? "").Split(separator);
    
        // Dynamically add the columns
        var table  = new DataTable();
        table.Columns.AddRange(fields.Select(field => new DataColumn(field)).ToArray());
    
        while (reader.Peek() >= 0)
        {
            var line = reader.ReadLine() ?? "";
    
            // Split the values considering the quoted field values
            var values = Regex.Split(line, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)")
                .Select((value, current) => value.Trim())
                .ToArray()
                ;
    
            // Add those values directly
            table.Rows.Add(values);
        }
    
        // Demonstrate the results
        foreach (DataRow row in table.Rows)
        {
            Console.WriteLine();
            foreach (DataColumn col in table.Columns)
            {
                Console.WriteLine("{0}={1}", col.ColumnName, row[col]);
            }
        }
    }
    

    【讨论】:

    • 更新为创建 DataTable
    • 如果实际解析的是 CSV,则存在一些基本问题。特别是,引用字段中的嵌入换行符会破坏解析,并且它不处理字段中的转义引号,并且它不会从引用字段中删除引号字符。该代码适用于给定的输入,但不适用于更一般的情况。
    猜你喜欢
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 2019-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    相关资源
    最近更新 更多