Как правильно разбить CSV с помощью функции С# split()?

Предположим, что у меня есть этот файл CSV:

NAME,ADDRESS,DATE
"Eko S. Wibowo", "Tamanan, Banguntapan, Bantul, DIY", "6/27/1979"

Я хотел бы сохранить каждый токен, заключенный с использованием двойных кавычек в массив, есть ли сейф, чтобы использовать это вместо функции String split()? В настоящее время я загружаю файл в RichTextBox, а затем используя его свойство Lines [], я делаю цикл для каждого элемента Lines [] и делаю это:

string[] line = s.Split(',');

s - ссылка на RichTextBox.Lines []. И, как вы можете ясно видеть, запятая внутри токена может легко испортить функцию split(). Итак, вместо того, чтобы закончиться с тремя токенами, как я этого хочу, я закончил с 6 жетонами

Любая помощь будет оценена!

Ответ 1

Вы также можете использовать регулярное выражение:

string input = "\"Eko S. Wibowo\", \"Tamanan, Banguntapan, Bantul, DIY\", \"6/27/1979\"";
string pattern = @"""\s*,\s*""";

// input.Substring(1, input.Length - 2) removes the first and last " from the string
string[] tokens = System.Text.RegularExpressions.Regex.Split(
    input.Substring(1, input.Length - 2), pattern);

Это даст вам:

Eko S. Wibowo
Tamanan, Banguntapan, Bantul, DIY
6/27/1979

Ответ 2

Я сделал это своим методом. Он просто подсчитывает символы " и '.
Улучшите это с учетом ваших потребностей.

    public List<string> SplitCsvLine(string s) {
        int i;
        int a = 0;
        int count = 0;
        List<string> str = new List<string>();
        for (i = 0; i < s.Length; i++) {
            switch (s[i]) {
                case ',':
                    if ((count & 1) == 0) {
                        str.Add(s.Substring(a, i - a));
                        a = i + 1;
                    }
                    break;
                case '"':
                case '\'': count++; break;
            }
        }
        str.Add(s.Substring(a));
        return str;
    }

Ответ 3

Это не точный ответ на ваш вопрос, но почему бы вам не использовать уже написанную библиотеку для управления CSV файлом, хорошим примером будет LinqToCsv. CSV можно разграничить с помощью различных знаков препинания. Более того, есть gotchas, которые уже обращаются к создателям библиотеки. Например, работа с строкой имени, работа с различными форматами дат и сопоставление строк с объектами С#.

Ответ 4

Если ваша линия CSV плотно упакована, проще всего использовать удаление конца и хвоста, упомянутое ранее, а затем простое разделение на соединительную строку

 string[] tokens = input.Substring(1, input.Length - 2).Split("\",\"");

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

Действительно полезно, если ваши данные выглядят как "Name", "1", "12/03/2018", "Add1, Add2, Add3", "other stuff",

Ответ 5

Вы можете заменить "," на ; затем разбивается ;

var values= s.Replace("\",\"",";").Split(';');

Ответ 6

Пять лет, но всегда есть кто-то новый, кто хочет разбить CSV.

Если ваши данные просты и предсказуемы (т.е. Никогда не имеют специальных символов, таких как запятые, кавычки и символы новой строки), вы можете сделать это с помощью split() или регулярного выражения.

Но чтобы поддерживать все нюансы формата CSV должным образом без суп-кода, вы действительно должны использовать библиотеку, где все волшебство уже было выяснено. Не заново изобретайте колесо (если вы не делаете это для удовольствия, конечно).

CsvHelper достаточно прост для использования:

https://joshclose.github.io/CsvHelper/2.x/

using (var parser = new CsvParser(textReader)
{
    while(true)
    {
        string[] line = parser.Read();

        if (line != null)
        {
            // do something
        }
        else
        {
            break;
        }
    }
}

Дополнительная дискуссия/тот же вопрос: Работа с запятыми в файле CSV