如何使用Microsoft.VisualBasic.FileIO.TextFieldParser为引用字段保留CSV字段空白?

如何使用Microsoft.VisualBasic.FileIO.TextFieldParser为引用字段保留CSV字段空白?,csv,textfieldparser,Csv,Textfieldparser,我正在使用Microsoft.VisualBasic.FileIO.TextFieldParser解析CSV数据。与我找到的用于解析CSV的免费软件库相比,它非常好。它做了我认为它应该写CSV的所有事情,除了它不保留用引号括起来的字段的前导/尾随空格。如果我将TrimWhiteSpace设置为false,它会这样做,但是它不会从没有括在引号中的字段中修剪空格。对于CSV,我希望它修剪非引用字段,而不是修剪引用字段 这就是我如何使用这个类: var parser = new TextField

我正在使用Microsoft.VisualBasic.FileIO.TextFieldParser解析CSV数据。与我找到的用于解析CSV的免费软件库相比,它非常好。它做了我认为它应该写CSV的所有事情,除了它不保留用引号括起来的字段的前导/尾随空格。如果我将TrimWhiteSpace设置为false,它会这样做,但是它不会从没有括在引号中的字段中修剪空格。对于CSV,我希望它修剪非引用字段,而不是修剪引用字段

这就是我如何使用这个类:

  var parser = new TextFieldParser(textReader) {Delimiters = new[] {","}};
  //TrimWhiteSpace is true by default
  var row1 = _textFieldParser.ReadFields();
  var row2 = _textFieldParser.ReadFields();
考虑以下数据:

 1 , 2 
" 1 ", " 2 "
对于TrimWhiteSpace==true,第1行和第2行都是[“1”,“2”]。 对于TrimWhiteSpace==false,第1行和第2行都是[“1”,“2”]


我想要的是第1行==[“1”,“2”]和第2行==[“1”,“2”]。

虽然回答得很晚,但我发现这个问题很有趣,而且投票率也很高,因为在所描述的条件下,没有内置的方法来保持空白,这让我感到惊讶

因此,假设输入与问题相同,并添加一行以保留双引号转义字符():

HasFieldsEnclosedInQuotes
设置为false,并使用简单的
Regex
处理包含在引号中的任何字段:

var separator = new string('=', 40);
Console.WriteLine(separator);
// demo only - show the input lines read from a text file 
var text = File.ReadAllText(inputPath);
var lines = text.Split(
    new string[] { Environment.NewLine }, 
    StringSplitOptions.None
);

using (var textReader = new StringReader(text))
{
    using (var parser = new TextFieldParser(textReader))
    {
        parser.TextFieldType = FieldType.Delimited;
        parser.SetDelimiters(",");
        parser.TrimWhiteSpace = true;
        parser.HasFieldsEnclosedInQuotes = false;
        // remove double quotes, since HasFieldsEnclosedInQuotes is false
        var regex = new Regex(@"
        # match double quote 
        \""    
        # if not immediately followed by a double quote
        (?!\"")
        ",
            RegexOptions.IgnorePatternWhitespace
        );

        var rowStart = 0;
        while (parser.PeekChars(1) != null)
        {
            Console.WriteLine(
                "row {0}: {1}", parser.LineNumber, lines[rowStart]
            );
            var fields = parser.ReadFields();
            for (int i = 0; i < fields.Length; ++i)
            {
                Console.WriteLine(
                    "parsed field[{0}] = [{1}]", i,
                    regex.Replace(fields[i], "")
                );
            }
            ++rowStart;
            Console.WriteLine(separator);
        }
    }
}

虽然回答得很晚,但我发现这个问题很有趣,而且投票率也很高,因为在我看来,在所描述的条件下,没有内置的方法来保持空白是令人惊讶的

因此,假设输入与问题相同,并添加一行以保留双引号转义字符():

HasFieldsEnclosedInQuotes
设置为false,并使用简单的
Regex
处理包含在引号中的任何字段:

var separator = new string('=', 40);
Console.WriteLine(separator);
// demo only - show the input lines read from a text file 
var text = File.ReadAllText(inputPath);
var lines = text.Split(
    new string[] { Environment.NewLine }, 
    StringSplitOptions.None
);

using (var textReader = new StringReader(text))
{
    using (var parser = new TextFieldParser(textReader))
    {
        parser.TextFieldType = FieldType.Delimited;
        parser.SetDelimiters(",");
        parser.TrimWhiteSpace = true;
        parser.HasFieldsEnclosedInQuotes = false;
        // remove double quotes, since HasFieldsEnclosedInQuotes is false
        var regex = new Regex(@"
        # match double quote 
        \""    
        # if not immediately followed by a double quote
        (?!\"")
        ",
            RegexOptions.IgnorePatternWhitespace
        );

        var rowStart = 0;
        while (parser.PeekChars(1) != null)
        {
            Console.WriteLine(
                "row {0}: {1}", parser.LineNumber, lines[rowStart]
            );
            var fields = parser.ReadFields();
            for (int i = 0; i < fields.Length; ++i)
            {
                Console.WriteLine(
                    "parsed field[{0}] = [{1}]", i,
                    regex.Replace(fields[i], "")
                );
            }
            ++rowStart;
            Console.WriteLine(separator);
        }
    }
}

我读了文档,搜索了网络(我认为这个网站不用说)。我使用我描述的库尝试了各种代码组合。你在说什么?你认为这不是一个好问题吗?在寻找相同答案时偶然发现了这个问题。已经标记了@工程机房的最后一个评论,因为它违反了这里的行为准则,这是我希望他们根据他们向史提夫提供“建议”而意识到的……我读了文档并搜索了网络(我认为这个网站不用说)。我使用我描述的库尝试了各种代码组合。你在说什么?你认为这不是一个好问题吗?在寻找相同答案时偶然发现了这个问题。已经将@EngineerDollery的最后一条评论标记为删除,因为它违反了SO的行为准则,我希望他们在向steve提供“建议”的基础上意识到这一点……感谢您的努力。但是,如果HasFieldsEnclosedInQuotes=false,解析器不会忽略字段中的逗号。例如,“a,b”,c导致[a][b][c],但应该是[a,b][c]。我非常确定,没有办法使用解析器实现我想要的功能。。。解析器有一个致命的缺陷(bug)。但是,我想我还是问问周围的人。谢谢你的努力,谢谢你的努力。但是,如果HasFieldsEnclosedInQuotes=false,解析器不会忽略字段中的逗号。例如,“a,b”,c导致[a][b][c],但应该是[a,b][c]。我非常确定,没有办法使用解析器实现我想要的功能。。。解析器有一个致命的缺陷(bug)。但是,我想我还是问问周围的人。谢谢你的努力。
========================================
row 1: 1 , 2
parsed field[0] = [1]
parsed field[1] = [2]
========================================
row 2: " 1 ", " 2 "
parsed field[0] = [ 1 ]
parsed field[1] = [ 2 ]
========================================
row 3: " a ""quoted"" word ", " hello world "
parsed field[0] = [ a "quoted" word ]
parsed field[1] = [ hello world ]
========================================