Разделитель заключен в текст в некоторых ячейках

Я делаю программное обеспечение, которое должно читать много данных из файла CSV. В CSV-файле используется ';' как разделитель. Недавно обнаружил, что текст в некоторых ячейках также завершается знаком «;». Каждый кортеж из файла является объектом, поэтому каждая ячейка в этой строке является атрибутом этого объекта. Я использую метод Split в C #, который возвращает массив строк. Из-за ';' в некоторых ячейках появляется ошибка: Массив выходит за рамки. Есть ли способы избавиться от этой ошибки, не удаляя ";" из каких ячеек?

Пример такого кортежа:

Ячейка1; ячейка2; ячейка3; еще ячейка3; ячейка4;

Cell3; stillCell3 - это одна ячейка, но метод Split этого не знает.


person user10024569    schedule 03.07.2018    source источник
comment
Было бы здорово, если бы вы могли предоставить минимально воспроизводимый пример.   -  person mjwills    schedule 03.07.2018
comment
Будьте очень осторожны с изобретением велосипеда - используйте nuget.org/packages/LumenWorksCsvReader.   -  person MineR    schedule 03.07.2018
comment
Можете выложить немного данных? Судя по вашему описанию, похоже, что их просто несколько ';' подряд, с чем было бы легко разобраться, но с вашим примером было бы невозможно разобраться.   -  person MineR    schedule 03.07.2018
comment
@MineR Нет, это данные моей компании   -  person user10024569    schedule 03.07.2018
comment
Тогда ваш пример, как данные появляются на самом деле? Или у вас есть что-то вроде Cell1; cell2; cell3 ;; cell4   -  person MineR    schedule 03.07.2018
comment
@MineR да, например. Но ; за ячейкой 3 должен находиться текст в ячейке 3   -  person user10024569    schedule 03.07.2018
comment
Ну, нет никакого программного способа сделать то, о чем вы просите. Вам нужно вручную очистить свои данные.   -  person MineR    schedule 03.07.2018


Ответы (3)


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

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

person PepitoSh    schedule 03.07.2018

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

Формат файла CSV

------------ РЕДАКТИРОВАТЬ 1 ---------------------

Рассмотрим этот пример. Это разделенный запятыми csv

введите описание изображения здесь

Здесь вы можете увидеть столбец «OK, 123; asw.wew» с символами ',' и ';'

Если мы откроем его с помощью блокнота или текстового редактора, мы увидим, что к нему автоматически добавляется escape-символ.

введите описание изображения здесь

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

-------------------------- РЕДАКТИРОВАТЬ 2 ------------------- -------

Вы можете воспользоваться .net классом TextFieldParser. Чтобы использовать его

  • добавить ссылку на Microsoft.VisualBasic (да, там написано VisualBasic, но он работает и на C #)
  • используйте класс Microsoft.VisualBasic.FileIO.TextFieldParser для анализа CSV файла

Вот пример кода:

using (TextFieldParser parser = new TextFieldParser(@"c:\test.csv"))
{
    parser.TextFieldType = FieldType.Delimited;
    parser.SetDelimiters(",");
    while (!parser.EndOfData) 
    {
        //Processing row
        string[] fields = parser.ReadFields();
        foreach (string field in fields) 
        {
            //TODO: Process field
        }
    }
}

Вот еще несколько полезных ссылок:

person Jinto Jacob    schedule 03.07.2018
comment
@ user10024569 проверьте правку. Откройте свой .csv в текстовом редакторе и, если возможно, поделитесь данными - person Jinto Jacob; 03.07.2018
comment
В CSV-файле около 1000 строк, которые мне пришлось бы изменить. - person user10024569; 03.07.2018
comment
Нет, в моем случае, когда я редактировал ячейку в Excel, она автоматически включала двойные кавычки. Можете ли вы проверить свой CSV, открыв его в текстовом редакторе, например в блокноте - person Jinto Jacob; 03.07.2018

Вы можете попробовать TextFieldParser у него есть много возможностей для чтения полей.

using (TextFieldParser lcsvReader = new TextFieldParser(new MemoryStream(<FILE_BYTES>), Encoding.Default))
{
    lcsvReader.Delimiters = new string[2] { ",", "\t" };
    lcsvReader.HasFieldsEnclosedInQuotes = true;
    lcsvReader.TrimWhiteSpace = true;
    while (!lcsvReader.EndOfData)
    {
        string[] fields = lcsvReader.ReadFields();
        //fields -- Actual field in CSV
    }
    lcsvReader.Close();
}
person Ashish Sapkale    schedule 03.07.2018