Чтение запятой CSV, который содержит валюту

1

Далее читается файл CSV с разделителями-запятыми.

Поле валюты, которое является третьим полем в каждой строке [2], является проблемой. Мне нужно разделить поля в запятой, но поле валюты иногда может быть большим, а также иметь их.

Как вы можете разделить файл csv, разделенный запятой, который содержит валюту.

Csv всегда соответствует 5 полям на каждой строке.

Первая строка в приведенном ниже примере работает, но вторая строка вызовет проблему.

3,09: 29 вечера, 20,00 евро, тест, тест

1,02: 55 утра, 10 000 евро, тест, тест

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);

        }

Любые ссылки или предложения будут оценены.

  • 0
    если поля разделены кавычками ( "abc", "d,e,f", "ghi" ), TextFieldParser и другие инструменты будут обрабатывать его, а String.Split - нет. Если вы делаете CSV, рассмотрите возможность использования точки с запятой в качестве разделителя полей
  • 0
    Извините, нет, я не имею никакого контроля над CSV, я думал о том, как после второй запятой игнорировать остальное, пока я не достигну «Нечто», но следующее что-то может быть только запятой ... Я немного потерян.
Показать ещё 3 комментария
Теги:
csv
streamreader

5 ответов

1
Лучший ответ

Вот взломать:

//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);
   }

 }

Это должно учитывать большие валюты (триллионы евро будут иметь больше запятых).

Надеюсь это поможет!

  • 0
    Очень мило спасибо
2

Раньше у меня была аналогичная проблема, и я обратился к 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);
    }
}

Дополнительную информацию можно найти здесь.

  • 0
    Я могу попробовать это спасибо, но сначала мне просто интересно, как textfieldparser скажет разницу в поле валюты? Я прочитаю об этом, но похоже, что пример будет иметь тот же результат ??
  • 0
    В моей ситуации одно из моих полей начало показывать несколько IP-адресов (через запятую), где оно использовалось для отображения номера телефона. Изменение моего String.Split() для обработки CSV, чтобы решить эту проблему.
Показать ещё 1 комментарий
1

Если длина строки динамическая

Мое решение этой проблемы заключается в реализации логики, которая ищет символ евро "€" в одном члене массива и радиусе ". в последующем члене. Если это условие выполнено, вы можете предположить, что столкнулись с особой ситуацией, о которой вы упомянули.

Если мы знаем, сколько полей должно быть на линии

В качестве альтернативы, если вы знаете, что вы должны всегда иметь одинаковое количество членов в каждом массиве (поля в каждой строке 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);
  • 0
    Спасибо, я думаю, что подойдет, я просто добавлю еще несколько сценариев, и это будет идеально для того, что мне нужно, спасибо, мельница. Марк и все остальные за вашу помощь
1

Грубая сила:

        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);

        }
0

Легкое решение

Вы можете видеть, что я конвертирую запятую внутри кавычек в другой символ. И работает для всех полей с одним и тем же случаем внутри строки. Вы можете поместить этот фрагмент внутри метода для повторного использования.

Пример строки: 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);

Результат: 40,3063,16,32,36,37,41,56,5, "$ 30¶600¶000,00", 12/4/2017

Наконец: просто замените свой характер выбора снова на запятую

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню