读取包含货币的逗号分隔 CSV

Reading a comma delimited CSV that contains currency

下面是从逗号分隔的 CSV 文件中读取的内容。

每行 [2] 中的第三个字段货币字段是问题所在。 我需要在逗号处拆分字段,但货币字段有时可能很大并且也有它们。

如何拆分包含货币的逗号分隔的 csv 文件??

csv 始终保持每行 5 个字段一致。

下面示例中的第一行有效,但第二行会导致问题。

3,09:29 pm,€20.00,测试,测试

1,02:55 am,€10,000.00,测试,测试

StreamReader fileIn = new StreamReader(path);
        //Read the file
        while (!fileIn.EndOfStream)
        {
           String line = fileIn.ReadLine();
           String[] pieces = line.Split(',');

           csvComplete cEve = new csvComplete (pieces[0], pieces[1], pieces[2], pieces[3], pieces[4]);// assign to class cEve
           entries.Add(cEve);

        }

如有任何链接或建议,我们将不胜感激。

我之前也遇到过类似的问题,于是求助于Microsoft.VisualBasic.FileIO.TextFieldParser。在你的情况下,试试这个:

using(TextFieldParser parser = new TextFieldParser(new StreamReader(path)){
    parser.Delimiters = new string [] {","};

    while(true){
        String[] pieces = parser.ReadFields();
        if(pieces == null)
            break;

        csvComplete cEve = new csvComplete (pieces[0], pieces[1], pieces[2], pieces[3], pieces[4]);// assign to class cEve
        entries.Add(cEve);
    }
}

可以找到更多信息 here

这是一个技巧:

//Read the file
while (!fileIn.EndOfStream)
{
   String line = fileIn.ReadLine();
   String[] pieces = line.Split(',');
   if(pieces.length > 5){
       String[] newPieces = new String[5];
       newPieces[0] = pieces[0];
       newPieces[1] = pieces[1];
       String currency = "";
       for(int i = 2; i < pieces.length - 2; i++){
           if(i == pieces.length -3)
               currency += pieces[i];
           else{
               currency += pieces[i] + ",";
           }
       }
       newPieces[2] = currency;
       newPieces[3] = pieces[pieces.length-2];
       newPieces[4] = pieces[pieces.length-1];
       csvComplete cEve = new csvComplete (newPieces[0], newPieces[1], newPieces[2], newPieces[3], newPieces[4]);// assign to class cEve
       entries.Add(cEve);
   }
   else{
       csvComplete cEve = new csvComplete (pieces[0], pieces[1], pieces[2], pieces[3], pieces[4]);// assign to class cEve
       entries.Add(cEve);
   }

 }

这应该考虑更大的货币(万亿欧元会有更多逗号)。

希望对您有所帮助!

暴力破解:

        StreamReader fileIn = new StreamReader(path);
        //Read the file
        while (!fileIn.EndOfStream)
        {
           String line = fileIn.ReadLine();
           String[] pieces = line.Split(',');
           if (pieces.Length == 5)
           {
               // Exactly 5 fields.   
               csvComplete cEve = new csvComplete (pieces[0], pieces[1], pieces[2], pieces[3], pieces[4]);// assign to class cEve
           }
           else if (pieces.Length == 6)
           {
               // Exactly 6 fields. We'll assume fields 1 and 2 should combine for currency string.
               csvComplete cEve = new csvComplete (pieces[0], pieces[1] + "," + pieces[2], pieces[3], pieces[4], pieces[5], pieces[6]);// assign to class cEve
           }
           else
           {
               // ?
           }
           entries.Add(cEve);

        }

如果行长度是动态的

我对这个问题的解决方案是实现在数组的一个成员和基数“.”中查找欧元符号“€”的逻辑。在随后的成员中。如果满足这个条件,那么你就可以认为你遇到了你所说的特殊情况。

如果我们知道一行应该有多少字段

或者,如果您知道每个数组(CSV 的每一行上的字段)中的成员数量应该始终相同,那么您的逻辑就会变得更简单。只需查找一个成员过多的数组。

以你的例子为例,我们假设每个数组应该恰好有五个成员:

0:索引/身份证号码

1: 子午线时间值

2:欧元货币金额

3: 测试数据1

4: 测试数据2

我们现在可以查找具有六个成员的数组并应用我们的业务逻辑:

String line = fileIn.ReadLine();
String[] pieces = line.Split(',');

if( pieces.Length == 6 ) 
{
    pieces[2] = String.Concat(pieces[2], pieces[3]);
    pieces[3] = pieces[4];
    pieces[4] = pieces[5];
}    

csvComplete cEve = new csvComplete (pieces[0], pieces[1], pieces[2], pieces[3], pieces[4]);// assign to class cEve
entries.Add(cEve);

轻量级解决方案

Has you can see I convert the comma inside the quotes in another character. And works for all the fields with the same case inside the string. You can put this snippet inside a method for reusability.

示例字符串: 40,3063,16,32,36,37,41,56,5,"$30,600,000.00",12/4/2017

                string sRead = sr.ReadLine();
                char[] srcTemp = sRead.ToCharArray();
                for (int i = 0; i < srcTemp.Length - 1; i++)
                {
                    if ((int)srcTemp[i] == 34)
                    {
                        int yCharnichart = 0;
                        for (int c = i + 1; c < srcTemp.Length - 1; c++)
                        {
                            if ((int)srcTemp[c] == 34) break;
                            if ((int)srcTemp[c] == 44) srcTemp[c] = (char)182;
                            yCharnichart++;
                        }
                        i += yCharnichart + 1;
                    }
                }
                StringBuilder sb = new StringBuilder();
                sb.Append(srcTemp);

Result: 40,3063,16,32,36,37,41,56,5,"¶600¶000.00",12/4/2017

最后:再次将您选择的字符替换为逗号

BOLSA = arRead[9].Replace((char)182, (char)44)