1

csv解析ライブラリを作成する(または既存のものを使用する)必要があります。

問題は、ファイルがさまざまな形式でさまざまな区切り記号を使用してアップロードされることです。たとえば、次のようになります。

File1:
field1; field2; field3; field4
field1; field2; field3; field4

File2:
feld1, field2, field3, field4
feld1, field2, field3, field4

File3:
"field1", "field2", "field3", "field4"
"field1", "field2", "field3", "field4"

どの記号が列の実際の区切り文字であるかをプログラムで理解するための最良の方法は何ですか?

シンボル統計分析を使用して独自のメソッドを作成することを考えていますが、既存のソリューションがあるのではないでしょうか。

4

1 に答える 1

1

私は正規表現を使用します(前回ほど多くの反対票を獲得しないことを望んでいます;))。基本的に以前にキャプチャしたグループを使用できる後方参照を利用しています。すべての行が同じセパレーターを使用している限り、同じファイルに異なるセパレーターを含めることもできます (ただし、それが役立つかどうかはわかりません)。

だから、これは私が正規表現を構築する方法です:

string csvItem = @"[""']?\w+[""']?";
string separator = @"\s*[,\.;-]\s*";
string pattern = string.Format(@"^({0}(?<sep>{1}){0})+(\k<sep>{0})*$",
    csvItem, separator);

csvItem は、csv 内の項目 (列) です。小文字または大文字、数字、およびアンダースコアを含めることができ、オプションで " または ' で囲むことができます。

セパレーターは項目を区切ります。これらの文字 ,.;- の 1 つと、0 個以上の空白文字で構成されます。

このパターンは、有効な行がセパレーターで区切られた少なくとも 2 つの csvItems で構成されることを示しています。後方参照に注意してください -> \k

ここにあります。これは、テスト ファイルの内容です。

field1; field2; field3; field4
field1; field2; field3; field4

feld1, field2, field3, field4
feld1, field2, field3, field4

"field1", "field2", "field3", "field4"
"field1", "field2", "field3", "field4"

サンプルのコンソール プロジェクト:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;

namespace csvParser {
    class Program {
        static void Main( string[ ] args ) {
            var lines = File.ReadAllLines( @"e:\prova.csv" );

            for ( int i = 0; i < lines.Length; i++ ) {
                string csvItem = @"[""']?\w+[""']?";
                string separator = @"\s*[,\.;-]\s*";
                string pattern = string.Format(@"^({0}(?<sep>{1}){0})+(\k<sep>{0})*$", csvItem, separator);

                var rex = new Regex( pattern, RegexOptions.Singleline );
                var match = rex.Match( lines[ i ] );

                if ( match == null ) {
                    Console.WriteLine( "No match on line {0}", i );
                    continue;
                }
                else {
                    string sep = match.Groups[ "sep" ].Value;

                    Console.WriteLine( "--- Line #{0} ---------------", i );
                    Console.WriteLine( "Line is '{0}'", lines[ i ] );
                    Console.WriteLine( "Separator is '{0}'", sep );

                    Console.WriteLine( "Items are:" );
                    foreach ( string item in lines[ i ].Split( sep ) )
                        Console.WriteLine( "\t'{0}'", item );

                    Console.WriteLine( );
                }
            }

            Console.ReadKey( );
        }
    }

    public static partial class Extension {
        public static string[ ] Split( this string str, string sep ) {
            return str.Split( new string[ ] { sep }, StringSplitOptions.RemoveEmptyEntries );
        }
    }
}

最後にその出力:

--- Line #0 ---------------
Line is 'field1; field2; field3; field4'
Separator is '; '
Items are:
        'field1'
        'field2'
        'field3'
        'field4'

--- Line #1 ---------------
Line is 'field1; field2; field3; field4'
Separator is '; '
Items are:
        'field1'
        'field2'
        'field3'
        'field4'

--- Line #2 ---------------
Line is ''
Separator is ''
Items are:

--- Line #3 ---------------
Line is 'feld1, field2, field3, field4'
Separator is ', '
Items are:
        'feld1'
        'field2'
        'field3'
        'field4'

--- Line #4 ---------------
Line is 'feld1, field2, field3, field4'
Separator is ', '
Items are:
        'feld1'
        'field2'
        'field3'
        'field4'

--- Line #5 ---------------
Line is ''
Separator is ''
Items are:

--- Line #6 ---------------
Line is '"field1", "field2", "field3", "field4"'
Separator is ', '
Items are:
        '"field1"'
        '"field2"'
        '"field3"'
        '"field4"'

--- Line #7 ---------------
Line is '"field1", "field2", "field3", "field4"'
Separator is ', '
Items are:
        '"field1"'
        '"field2"'
        '"field3"'
        '"field4"'

残念ながら、正規表現は空の行もキャプチャします。それを修正しようとしています:)

于 2012-07-18T14:08:48.663 に答える