Работа с запятыми в файле CSV - PullRequest
442 голосов
/ 20 апреля 2009

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

Вот некоторые идеи, которые мы рассматриваем: цитируемые идентификаторы (значение, значения, и т. Д.) Или использование | вместо запятой. Самая большая проблема заключается в том, что нам нужно сделать это проще, иначе клиент этого не сделает.

Ответы [ 24 ]

3 голосов
/ 10 мая 2017

В Европе у нас эта проблема должна возникать раньше, чем этот вопрос. В Европе мы используем все запятые для десятичной точки. Смотрите эти цифры ниже:

| American      | Europe        |
| ------------- | ------------- |
| 0.5           | 0,5           |
| 3.14159265359 | 3,14159265359 |
| 17.54         | 17,54         |
| 175,186.15    | 175.186,15    |

Так что невозможно использовать запятую для файлов CSV. По этой причине CSV-файлы в Европе разделяются точкой с запятой (;) .

Такие программы, как Microsoft Excel, могут читать файлы с точкой с запятой, и можно переключаться с разделителя. Вы даже можете использовать вкладку (\t) в качестве разделителя. См. этот ответ от Ужинающего пользователя .

3 голосов
/ 01 мая 2014

Если вы хотите заново изобрести колесо, вам может помочь:

public static IEnumerable<string> SplitCSV(string line)
{
    var s = new StringBuilder();
    bool escaped = false, inQuotes = false;
    foreach (char c in line)
    {
        if (c == ',' && !inQuotes)
        {
            yield return s.ToString();
            s.Clear();
        }
        else if (c == '\\' && !escaped)
        {
            escaped = true;
        }
        else if (c == '"' && !escaped)
        {
            inQuotes = !inQuotes;
        }
        else
        {
            escaped = false;
            s.Append(c);
        }
    }
    yield return s.ToString();
}
2 голосов
/ 13 декабря 2013

Если вы заинтересованы в более образовательном упражнении по анализу файлов в целом (на примере CSV), вы можете проверить эту статью Джулиана Бакнолла. Мне нравится статья, потому что она разбивает вещи на гораздо более мелкие проблемы, которые гораздо менее непреодолимы. Сначала вы создаете грамматику, и когда у вас есть хорошая грамматика, преобразование грамматики в код является относительно простым и методичным процессом.

В статье используется C # и внизу ссылка для загрузки кода.

0 голосов
/ 06 июня 2018
    public static IEnumerable<string> LineSplitter(this string line, char 
         separator, char skip = '"')
    {
        var fieldStart = 0;
        for (var i = 0; i < line.Length; i++)
        {
            if (line[i] == separator)
            {
                yield return line.Substring(fieldStart, i - fieldStart);
                fieldStart = i + 1;
            }
            else if (i == line.Length - 1)
            {
                yield return line.Substring(fieldStart, i - fieldStart + 1);
                fieldStart = i + 1;
            }

            if (line[i] == '"')
                for (i++; i < line.Length && line[i] != skip; i++) { }
        }

        if (line[line.Length - 1] == separator)
        {
            yield return string.Empty;
        }
    }
0 голосов
/ 18 ноября 2017

Самое простое решение, которое я нашел, это то, которое использует LibreOffice:

  1. Заменить все буквальные " на
  2. Положите двойные кавычки вокруг вашей строки

Вы также можете использовать тот, который использует Excel:

  1. Заменить все буквальные " на ""
  2. Положите двойные кавычки вокруг вашей строки

Обратите внимание, что другие люди рекомендовали сделать только шаг 2 выше, но это не работает со строками, где за " следует ,, как в CSV, где вы хотите иметь один столбец со строкой hello",world, поскольку CSV будет читать:

"hello",world"

Что интерпретируется как строка с двумя столбцами: hello и world"

0 голосов
/ 17 июля 2016

Используйте символ табуляции (\ t) для разделения полей.

0 голосов
/ 10 февраля 2016

Я обычно делаю это в моих процедурах разбора CSV-файлов. Предположим, что переменная 'line' - это одна строка в файле CSV, а все значения столбцов заключены в двойные кавычки. После выполнения двух следующих строк вы получите столбцы CSV в коллекции 'values'.

// The below two lines will split the columns as well as trim the DBOULE QUOTES around values but NOT within them
    string trimmedLine = line.Trim(new char[] { '\"' });
    List<string> values = trimmedLine.Split(new string[] { "\",\"" }, StringSplitOptions.None).ToList();
0 голосов
/ 13 августа 2015

Я обычно URL-кодирую поля, которые могут иметь любые запятые или любые специальные символы. А затем декодируйте его, когда он используется / отображается на любом визуальном носителе.

(запятые становятся% 2C)

У каждого языка должны быть методы для URL-кодирования и декодирования строк.

например, в Java

URLEncoder.encode(myString,"UTF-8"); //to encode
URLDecoder.decode(myEncodedstring, "UTF-8"); //to decode

Я знаю, что это очень общее решение, и оно не может быть идеальным для ситуации, когда пользователь хочет просмотреть содержимое csv-файла вручную.

0 голосов
/ 22 декабря 2014

Во-первых, давайте спросим себя: «Почему мы чувствуем необходимость обрабатывать запятые по-разному для файлов CSV?»

Для меня ответ таков: «Потому что, когда я экспортирую данные в файл CSV, запятые в поле исчезают, и мое поле разделяется на несколько полей, в которых запятые появляются в исходных данных». (Это потому, что запятая является символом-разделителем полей CSV.)

В зависимости от вашей ситуации, точки с запятой также могут использоваться в качестве разделителей полей CSV.

Учитывая мои требования, я могу использовать символ, например, одиночную кавычку с низким 9, которая выглядит как запятая.

Итак, вот как вы можете сделать это в Go:

// Replace special CSV characters with single low-9 quotation mark
func Scrub(a interface{}) string {
    s := fmt.Sprint(a)
    s = strings.Replace(s, ",", "‚", -1)
    s = strings.Replace(s, ";", "‚", -1)
    return s
}

Второй символ с запятой в функции замены - десятичное 8218.

Имейте в виду, что если у вас есть клиенты, которые могут иметь программы чтения текста только для ascii, этот символ decima 8218 не будет выглядеть как запятая. Если это ваш случай, я бы рекомендовал окружить поле запятой (или точкой с запятой) двойными кавычками в RFC 4128: https://tools.ietf.org/html/rfc4180

0 голосов
/ 20 апреля 2009

Поскольку речь идет об общих методах, давайте начнем с правил большого пальца:

  1. Не используйте CSV, используйте XML с библиотекой для чтения и записи XML-файла.

  2. Если вы должны использовать CSV. Сделайте это правильно и используйте бесплатную библиотеку для анализа и хранения файлов CSV.

Для обоснования 1) большинство синтаксических анализаторов CSV не поддерживают кодирование, поэтому, если вы не имеете дело с US-ASCII, у вас возникнут проблемы. Например, Excel 2002 хранит CSV в локальной кодировке без каких-либо замечаний о кодировке. Стандарт CSV не получил широкого распространения :(. С другой стороны, стандарт XML хорошо принят и хорошо обрабатывает кодировки.

Чтобы оправдать 2), существует множество парсеров csv для почти всех языков, поэтому нет необходимости изобретать велосипед, даже если решения выглядят довольно просто.

Чтобы назвать несколько:

  • для Python использовать встроенный CSV модуль

  • для проверки perl CPAN и Text :: CSV

  • для php использовать встроенные функции fgetcsv / fputcsv

  • для проверки Java SuperCVS библиотека

На самом деле нет необходимости реализовывать это вручную, если вы не собираетесь анализировать это на встроенном устройстве.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...