C# TextFieldParser从字符串而不是文件解析CSV

C# TextFieldParser从字符串而不是文件解析CSV,c#,csv,textfieldparser,C#,Csv,Textfieldparser,使用Microsoft.VisualBasic.FileIO中的TextFieldParser,可以解析CSV文件,如下所示: using (TextFieldParser parser = new TextFieldParser(CSVPath)) { parser.TextFieldType = FieldType.Delimited; parser.SetDelimiters(","); parser.HasFieldsEnclosedInQuotes = true

使用Microsoft.VisualBasic.FileIO中的TextFieldParser,可以解析CSV文件,如下所示:

using (TextFieldParser parser = new TextFieldParser(CSVPath))
{
    parser.TextFieldType = FieldType.Delimited;
    parser.SetDelimiters(",");
    parser.HasFieldsEnclosedInQuotes = true;
    while (!parser.EndOfData) { string[] fields = parser.ReadFields(); }
}
但是,这依赖于使用CSV文件路径初始化TextFieldParser。是否可能在传入包含数据记录本身的字符串时产生相同的效果

例如,对于值为
Data1,6.5,“Data3”“MoreData”“”
(注意,由于转义引号,最后一个数据用引号括起来)保存在字符串变量中的CSV数据记录,我是否可以将数据转换为如下所示的字符串数组:

[0] = "Data1"
[1] = "6.5"
[2] = "Data3 \"MoreData\""

您还可以从流或文本阅读器实例化TextFieldParser。它不必是字符串路径。所以,你可以流式传输任何你喜欢的东西,只要你能把它放到流中。可能只是一个记忆流

例如


包含原始字符串的StringReader可以传递到新的TextFieldParser中,并以相同的方式进行处理

StringReader sr = new StringReader("Data1,6.5,\"Data3,\"\"MoreData\"\"\"");
using (var parser = new TextFieldParser(sr))
{
    parser.TextFieldType = FieldType.Delimited;
    parser.SetDelimiters(",");
    parser.HasFieldsEnclosedInQuotes = true;
    while (!parser.EndOfData)
    {
        Console.WriteLine("Line:");
        var fields = parser.ReadFields();
        foreach (var field in fields)
        {
            Console.WriteLine("\tField: " + field);
        }
    }
}
输出到控制台:

行:
字段:Data1
字段:6.5
字段:数据3,“更多数据”

使用TextFieldParser是最简单、最简单的方法,正如公认的答案中所说的,您完全可以从流中实例化它

尽管如此,我还是想用一条有价值的信息来完成这个被接受的答案,这条信息是给所有在G**gle搜索后来到这里的人的:

我发现了一个非常简单的解析器,它使用以下代码读取CSV数据:

var res = new List<string[]>();

using (TextFieldParser parser = new TextFieldParser(filepath))
{
    parser.CommentTokens = new string[] { "#" };
    parser.SetDelimiters(new string[] { ";" });
    parser.HasFieldsEnclosedInQuotes = true;

    // Skip over header line.
    parser.ReadLine();

    while (!parser.EndOfData)
    {
        res.Add(parser.ReadFields());
    }
}
var res=new List();
使用(TextFieldParser=newtextfieldparser(filepath))
{
parser.CommentTokens=新字符串[]{“#”};
SetDelimiters(新字符串[]{;“});
parser.HasFieldsEnclosedInQuotes=true;
//跳过标题行。
parser.ReadLine();
而(!parser.EndOfData)
{
res.Add(parser.ReadFields());
}
}
请务必小心parser.ReadLine(),因为如果至少有一个标头字段包含CRLF,它可能会产生不需要的结果。 在这种情况下,您的第一个读取行将在第一个CRLF之后包含标题的剩余部分

因此,请注意,最好使用ReadFields读取整个文件,这些ReadFields非常注意格式良好的字段(参见CSV RFC at),包括标题,然后在需要时忽略第一行

4180 RFC已经足够完整,如果您也想实现一个合适的CSV编写器,它将为您提供一条道路


与CSV成员一起玩得开心。

您是否尝试过建议的输入?如果是,并且你成功了,请添加相关代码…不太容易。。。使用OP中的输入数据。无法使用TextFieldParser解析该文本。。。试着这样做:Data1,6.5,\'Data3,\'MoreData\'(至少我不能这么做)对我使用我的代码很好,尽管您需要输入的字符串必须是正确的:
“Data1,6.5,\'Data3\”,“MoreData\”\r\n“
。您上面提到的一个在Data3之后缺少转义引号。正是缺少的引号造成了问题。再次查看预期输出。Data3,“MoreData”作为数组的第三个元素,而不是Data3作为数组的第三个元素和“MoreData”作为数组的第四个元素,乍一看可能有点让人困惑,因为CSV文件在字段周围使用引号或逗号。只有3个字段,最后一个用引号括起来。这很有效。我可以核实。这样一个简单的回答节省了我很多时间。
var res = new List<string[]>();

using (TextFieldParser parser = new TextFieldParser(filepath))
{
    parser.CommentTokens = new string[] { "#" };
    parser.SetDelimiters(new string[] { ";" });
    parser.HasFieldsEnclosedInQuotes = true;

    // Skip over header line.
    parser.ReadLine();

    while (!parser.EndOfData)
    {
        res.Add(parser.ReadFields());
    }
}