Как правильно разбить 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