Далее читается файл 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);
}
Любые ссылки или предложения будут оценены.
Вот взломать:
//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);
}
}
Это должно учитывать большие валюты (триллионы евро будут иметь больше запятых).
Надеюсь это поможет!
Раньше у меня была аналогичная проблема, и я обратился к 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);
}
}
Дополнительную информацию можно найти здесь.
String.Split()
для обработки CSV, чтобы решить эту проблему.
Если длина строки динамическая
Мое решение этой проблемы заключается в реализации логики, которая ищет символ евро "€" в одном члене массива и радиусе ". в последующем члене. Если это условие выполнено, вы можете предположить, что столкнулись с особой ситуацией, о которой вы упомянули.
Если мы знаем, сколько полей должно быть на линии
В качестве альтернативы, если вы знаете, что вы должны всегда иметь одинаковое количество членов в каждом массиве (поля в каждой строке 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);
Грубая сила:
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);
}
Вы можете видеть, что я конвертирую запятую внутри кавычек в другой символ. И работает для всех полей с одним и тем же случаем внутри строки. Вы можете поместить этот фрагмент внутри метода для повторного использования.
Пример строки: 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)
"abc", "d,e,f", "ghi"
), TextFieldParser и другие инструменты будут обрабатывать его, аString.Split
- нет. Если вы делаете CSV, рассмотрите возможность использования точки с запятой в качестве разделителя полей