1

Microsoft.VisualBasic.FileIO.TextFieldParser を使用して CSV データを解析しています。CSV を解析するために私が見つけたフリーウェア ライブラリと比較して、これは非常に優れています。引用符で囲まれたフィールドの先頭/末尾のスペースを保持しないことを除いて、WRT 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 の場合、row1 と row2 の両方が ["1", "2"] です。TrimWhiteSpace==false の場合、row1 と row2 の両方が [" 1 ", " 2 "] です。

私が欲しいのは、row1==["1", "2"] と row2==[" 1 ", " 2 "] です。

4

1 に答える 1

0

回答がかなり遅れましたが、IMO が記述された条件下で空白を保持する組み込みの方法がないのは驚くべきことであるため、質問は興味深いものであり、賛成票を投じられました。

したがって、質問と同じ入力を想定し、二重引用符のエスケープ文字 (直後の二重引用符)も保持する行を追加します。

1 , 2 
" 1 ", " 2 "
" a ""quoted"" word ", " hello world "

false に設定HasFieldsEnclosedInQuotesし、単純な を使用して引用符で囲まれたフィールドを処理します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);
        }
    }
}

出力:

========================================
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 ]
========================================
于 2016-02-15T17:38:47.183 に答える