3

私はcsvパーサー用に次のコードを持っています

string input = wholeFile;
IList<string> wholeFileArray = new List<string>();
int start = 0;
bool inQuotes = false;
for (int current = 0; current < input.Length; current++)
{
   // test each character before and after to determine if it is a valid quote, or a quote within a quote.
   int test_backward = (current == 0 ? 1 : current) - 1;
   int test_forward = (current == input.Length - 1 ? input.Length - 2 : current) + 1;
   bool valid_quote = input[test_backward] == ',' || input[test_forward] == ',' || input[test_forward] == '\r';
    if (input[current] == '\"') // toggle state
    {
        inQuotes = !inQuotes;
    }
    bool atLastChar = (current == input.Length - 1);
    if (atLastChar)
    {
        wholeFileArray.Add(input.Substring(start));
    }
    else if (input[current] == ',' && !inQuotes)
    {
        wholeFileArray.Add(input.Substring(start, current - start));
        start = current + 1;
    }
}

文字列を取り、そのような二重引用符文字列内にない,場合は分割します。,"something,foobar"

私の問題は、私の文字列の悪党"が私のプロセス全体を台無しにしていることです.

例:"bla bla","bla bla2",3,4,"5","bla"bla","End" 結果

  • 「ブラブラ」
  • 「ブラブラ2」
  • 3
  • 4
  • 「5」
  • "bla"bla","End"

不正を許可するようにコードを変更するにはどうすればよいですか"

「有効な」終了引用符の後には常にコンマ (,) またはコントロール ラインフィードが続きます

追加 これで修正されたようです

// test each character before and after to determine if it is a valid quote, or a quote within a quote.
int test_backward = (current == 0 ? 1 : current) - 1;
int test_forward = (current == input.Length - 1 ? input.Length - 2 : current) + 1;
bool valid_quote = input[test_backward] == ',' || input[test_forward] == ',' || input[test_forward] == '\r';
4

3 に答える 3

2

次のようなことを試してください:

if (input[current] == '"' && // 1
    (!inQuotes || // 2
    current + 1 == input.Length || // 3
    input[current + 1] == '\r' || // 4
    input[current + 1] == '\n' || // 5
        (input[current + 1] == ',' && // 6
            (current + 2 == input.Length || // 7
            input[current + 2] == '\r' || // 8
            input[current + 2] == '\n' || // 9
            input[current + 2] == '"' || // 10
                (input[current + 2] >= '0' && input[current + 2] <= '9'))))) // 11
// toggle state

ただし、さまざまな概念レベルでやりたいことが間違っていることに注意してください。

正しい引用符は、開始引用符2または文字列3の最後の文字である引用符、またはその後に\r 4または\n 5が続く引用符、またはその後に文字列7または文字列の最後の文字である, 6が続く引用符です。その後に8または9または引用符10または数字11が続きます。\r \n "

于 2013-08-08T08:39:09.097 に答える
0

別の方法として、引用符の中に a がない限り、 Microsoft.VisualBasic.FileIO.TextFieldParser,を調べることができます。

次のコード スニペット:

using Microsoft.VisualBasic.FileIO;


using (TextFieldParser parser = new TextFieldParser(fileName))
{

    parser.Delimiters = new string[] { "," };

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

上記のコード スニペットは、次のようにサンプル行を含む配列を生成します。

「ブラブラ」
「ブラブラ2」
3
4
5
「ブラブラ」
"終わり"

明らかに、これはコードに適応させる必要があり、最適な解決策ではありません (特に,引用符の間にある場合)。

于 2013-08-08T08:36:44.673 に答える