如何在解析csv文件时保留引号?

时间:2013-08-22 14:21:56

标签: c# csv double-quotes textfieldparser

我正在使用Microsoft.VisualBasic.FileIO.TextFieldParser来读取csv文件,编辑它,然后解析它。

问题是解析后没有保留引号。

我尝试使用parser.HasFieldsEnclosedInQuotes = true;,但由于某种原因似乎没有保留引号。

如果某个字段包含引号,例如:  前

 "some, field" 

 some, field 

作为两个单独的领域

这是我的方法

public static void CleanStaffFile()
    {
        String path = @"C:\file.csv";
        String dpath = String.Format(@"C:\file_{0}.csv",DateTime.Now.ToString("MMddyyHHmmss"));
        List<String> lines = new List<String>();

        if (File.Exists(path))
        {
            using (TextFieldParser parser = new TextFieldParser(path))
            {
                parser.HasFieldsEnclosedInQuotes = true;
                parser.Delimiters = new string[] { "," };

                while (!parser.EndOfData)
                {
                    string[] parts = parser.ReadFields();

                    if (parts == null)
                    {
                        break;
                    }

                    if ((parts[12] != "") && (parts[12] != "*,116"))
                    {
                        parts[12] = parts[12].Substring(0, 3);
                    }
                    else
                    {
                        parts[12] = "0";
                    }

                    lines.Add(string.Join(",", parts));
                }
            }

            using (StreamWriter writer = new StreamWriter(dpath, false))
            {
                foreach (String line in lines)
                    writer.WriteLine(line);
            }

        }

        MessageBox.Show("CSV file successfully processed :\n");
    }

2 个答案:

答案 0 :(得分:1)

所以你想在string.Join(",", parts)修改后引用它?然后它很容易,因为只有包含分隔符的字段之前用引号括起来。只需在String.Join之前再次添加它们。

所以之前(和期望):

"some, field" 

之后(不需要):

some, field 

这应该有效:

string[] fields = parser.ReadFields();
// insert your logic here ....
var newFields = fields 
    .Select(f => f.Contains(",") ? string.Format("\"{0}\"", f) : f);
lines.Add(string.Join(",", newFields));

修改

  

即使不包含逗号

,我也想保留引号

然后它更容易:

var newFields = fields.Select(f => string.Format("\"{0}\"", f));

答案 1 :(得分:0)

{MS}页面中使用TextFieldParser.HasFieldsEnclosedInQuotes属性如下:

  

如果属性为True,则解析器假定字段用引号(“”)括起来,并且可能包含行结尾。

     

如果字段用引号括起来,例如abc, "field2a,field2b", field3且此属性为True,则引号中的所有文本都将按原样返回;此示例将返回abc|field2a,field2b|field3。将此属性设置为False将使此示例返回abc|"field2a|field2b"|field3

引号将指示字段的开头和结尾,然后可以包含用于正常分隔字段的字符。如果您的数据本身有引号,则需要将HasFieldsEnclosedInQuotes设置为false

如果您的数据字段可以同时包含分隔符和引号,则需要在解析之前开始转义引号,这是一个问题。基本上,您将超越简单CSV文件的功能。