Я ищу предложения о том, как обрабатывать CSV-файл, который создается, затем загружается нашими клиентами и может иметь запятую в значении, таком как название компании.
Вот некоторые идеи, которые мы рассматриваем: цитируемые идентификаторы (значение, значения, и т. Д.) Или использование | вместо запятой. Самая большая проблема заключается в том, что нам нужно сделать это проще, иначе клиент этого не сделает.
Ответы:
Как уже говорили другие, вам нужно избегать значений, которые включают кавычки. Вот небольшой CSV-ридер на C♯, который поддерживает значения в кавычках, включая встроенные кавычки и возврат каретки.
Кстати, это проверенный модулем код. Я публикую его сейчас, потому что этот вопрос, кажется, часто поднимается, и другие могут не захотеть целую библиотеку, когда подойдет простая поддержка CSV.
Вы можете использовать его следующим образом:
Вот классы. Обратите внимание, что вы также можете использовать эту
Csv.Escape
функцию для написания действительного CSV.источник
На 2017 год csv полностью указан - RFC 4180.
Это очень распространенная спецификация, полностью охватываемая многими библиотеками ( пример ).
Просто используйте любую легкодоступную библиотеку CSV - то есть RFC 4180.
На самом деле есть спецификация для формата CSV и способ обработки запятых:
http://tools.ietf.org/html/rfc4180
Итак, чтобы иметь значения
foo
иbar,baz
, вы делаете это:Еще одно важное требование для рассмотрения (также из спецификации):
источник
System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator
.Формат CSV использует запятые для разделения значений, значения, содержащие возврат каретки, переводы строки, запятые или двойные кавычки, заключаются в двойные кавычки. Значения, содержащие двойные кавычки, заключаются в кавычки, и каждая буквальная кавычка экранируется непосредственно предшествующей кавычкой: например, 3 значения:
будет закодирован как:
Любое поле может быть заключено в кавычки, но только те поля, которые содержат запятые, CR / NL или кавычки, должны быть заключены в кавычки.
Не существует реального стандарта для формата CSV, но почти все приложения следуют соглашениям, описанным здесь . RFC, который упоминался в другом месте, не является стандартом для CSV, это RFC для использования CSV в MIME и содержит некоторые нетрадиционные и ненужные ограничения, которые делают его бесполезным вне MIME.
Причиной, которую многие CSV-модули, которые я видел, не приспосабливают, является тот факт, что несколько строк могут быть закодированы в одном поле, что означает, что вы не можете предполагать, что каждая строка является отдельной записью, либо вы не должны допускать переносы в вашем данные или будьте готовы справиться с этим.
источник
Положите двойные кавычки вокруг строк. Это обычно то, что делает Excel .
Ала Эли,
источник
Вы можете поставить двойные кавычки вокруг полей. Мне не нравится этот подход, поскольку он добавляет еще один специальный символ (двойная кавычка). Просто определите escape-символ (обычно с обратной косой чертой) и используйте его везде, где вам нужно что-то экранировать:
Вам не нужно пытаться сопоставлять кавычки, и у вас меньше исключений для разбора. Это также упрощает ваш код.
источник
Через nuget доступна библиотека для работы с практически любым правильно сформированным CSV (.net) - CsvHelper
Пример для сопоставления с классом:
Пример для чтения отдельных полей:
Разрешение клиенту управлять форматом файла:
,
это стандартный разделитель полей,"
это стандартное значение, используемое для экранирования полей, которые содержат разделитель, кавычку или конец строки.Использовать (например)
#
для полей и'
для экранирования:Больше документации
источник
CsvHelper
библиотеки для решения проблемы ОП.Как упомянуто в моем комментарии к ответу гарпо, его решение хорошо и работает в большинстве случаев, однако в некоторых сценариях, когда запятые как непосредственно примыкают друг к другу, он не разделяется на запятые.
Это связано с тем, что строка Regex неожиданно ведет себя как строка vertabim. Для правильного поведения всех «символов» в строке регулярного выражения необходимо экранировать вручную без использования экранирования vertabim.
То есть. Регулярное выражение должно быть таким, используя ручные экранированные символы:
",(?=(?:[^\"\"]*\"\"[^\"\"]*\"\")*(?![^\"\"]*\"\"))"
что переводится на
",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))"
При использовании строки vertabim
@",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))"
она ведет себя следующим образом, как вы можете видеть, если вы отлаживаете регулярное выражение:Итак, в заключение, я рекомендую решение Harpo, но остерегайтесь этой маленькой ошибки!
Я включил в CsvReader немного необязательный отказоустойчивый, чтобы уведомить вас, если эта ошибка происходит (если у вас есть заранее известное количество столбцов):
Это может быть введено через конструктор:
источник
[^""]
же, как[^"]
? Дублирование символа в спецификации класса символа является избыточным, верно?Добавьте ссылку на Microsoft.VisualBasic (да, он говорит VisualBasic, но он работает и в C # точно так же - помните, что в конце все это просто IL).
Используйте
Microsoft.VisualBasic.FileIO.TextFieldParser
класс для разбора файла CSV. Вот пример кода:источник
parser.HasFieldsEnclosedInQuotes = true;
и входной файл должен будет заключать поля, содержащие запятые в кавычки, в соответствии со спецификацией CSV - Excel это уже делает.Вы можете использовать альтернативные «разделители», такие как «;» или "|" но самым простым может быть просто цитирование, которое поддерживается большинством (приличных) библиотек CSV и большинством приличных электронных таблиц.
Для более на CSV разделителях и в спецификации для стандартного формата для описания разделителей и цитирования видеть этот веб - страницу
источник
В случае , если вы на * NIX-системе , имеет доступ к
sed
и может быть один или несколько нежелательных запятые только в конкретной области вашего CSV, вы можете использовать следующий Однострочник для того , чтобы вложить их в"
качестве RFC4180 раздела 2 предлагает:В зависимости от того, в каком поле могут находиться нежелательные запятые, вам придется изменить / расширить группы захвата регулярного выражения (и подстановки).
В приведенном выше примере четвертое поле (из шести) будет заключено в кавычки.
В сочетании с параметром
--in-place
-option вы можете применить эти изменения непосредственно к файлу.Чтобы «построить» правильное регулярное выражение, нужно следовать простому принципу:
[^,]*,
и складываете их все вместе в группу захвата.(.*)
.,.*
и складываете их все вместе в группу захвата.Вот краткий обзор различных возможных регулярных выражений / замен в зависимости от конкретной области. Если не дано, замена есть
\1"\2"\3
.Если вы хотите удалить ненужные запятую (и)
sed
вместо того, чтобы заключать их в кавычки, обратитесь к этому ответу .источник
Если вы хотите заново изобрести колесо, вам может помочь следующее:
источник
В Европе у нас эта проблема должна появиться раньше, чем этот вопрос. В Европе мы используем все запятые для десятичной точки. Смотрите эти цифры ниже:
Поэтому невозможно использовать запятую для файлов CSV. По этой причине файлы CSV в Европе разделяются точкой с запятой (
;
) .Такие программы, как Microsoft Excel, могут читать файлы с точкой с запятой, и можно переключаться с разделителя. Вы даже можете использовать tab (
\t
) в качестве разделителя. Смотрите этот ответ от пользователя Ужина .источник
Если вы заинтересованы в более образовательном упражнении о том, как анализировать файлы в целом (на примере CSV), вы можете прочитать эту статью Джулиана Бакнолла. Мне нравится статья, потому что она разбивает вещи на гораздо более мелкие проблемы, которые гораздо менее непреодолимы. Сначала вы создаете грамматику, и когда у вас есть хорошая грамматика, преобразование грамматики в код является относительно простым и методичным процессом.
Статья использует C # и имеет ссылку внизу для загрузки кода.
источник
Вот изящный маленький обходной путь:
Вместо этого вы можете использовать греческий знак нижней цифры (U + 0375)
Похоже, это ͵
Использование этого метода также экономит много ресурсов ...
источник
Просто используйте SoftCircuits.CsvParser на NuGet. Он будет обрабатывать все эти детали для вас и эффективно обрабатывает очень большие файлы. И, при необходимости, он может даже импортировать / экспортировать объекты, сопоставляя столбцы со свойствами объекта. Кроме того, мое тестирование показало, что оно в среднем почти в 4 раза быстрее, чем популярный CsvHelper.
источник
Поскольку это касается общих практик, давайте начнем с правил большого пальца:
Не используйте CSV, используйте XML с библиотекой для чтения и записи XML-файла.
Если вы должны использовать CSV. Сделайте это правильно и используйте бесплатную библиотеку для анализа и хранения файлов CSV.
Для обоснования 1) большинство синтаксических анализаторов CSV не поддерживают кодирование, поэтому, если вы не имеете дело с US-ASCII, у вас возникнут проблемы. Например, Excel 2002 хранит CSV в локальной кодировке без каких-либо замечаний о кодировке. Стандарт CSV не получил широкого распространения :(. С другой стороны, стандарт XML хорошо принят и хорошо обрабатывает кодировки.
Чтобы оправдать 2), существует множество парсеров csv для почти всех языков, поэтому нет необходимости изобретать колесо, даже если решения выглядят довольно просто.
Чтобы назвать несколько:
для Python использовать встроенный модуль CSV
для проверки Perl CPAN и Text :: CSV
для php используйте встроенные функции fgetcsv / fputcsv
для проверки Java библиотеки SuperCVS
На самом деле нет необходимости реализовывать это вручную, если вы не собираетесь анализировать это на встроенном устройстве.
источник
Вы можете прочитать файл CSV, как это.
это использует расколы и заботится о пробелах.
источник
Во-первых, давайте спросим себя: «Почему мы чувствуем необходимость обрабатывать запятые по-разному для файлов CSV?»
Для меня ответ таков: «Потому что, когда я экспортирую данные в CSV-файл, запятые в поле исчезают, и мое поле разделяется на несколько полей, где запятые появляются в исходных данных». (Это потому, что запятая является символом разделителя полей CSV.)
В зависимости от вашей ситуации, точки с запятой могут также использоваться в качестве разделителей полей CSV.
Учитывая мои требования, я могу использовать символ, например, одинарную кавычку, которая выглядит как запятая.
Итак, вот как вы можете сделать это в Go:
Второй символ с запятой в функции замены - десятичное 8218.
Имейте в виду, что если у вас есть клиенты, которые могут иметь программы чтения текста только для ascii, этот символ decima 8218 не будет выглядеть как запятая. Если это ваш случай, я бы рекомендовал окружить поле запятой (или точкой с запятой) двойными кавычками в RFC 4128: https://tools.ietf.org/html/rfc4180
источник
Я обычно URL-кодирую поля, которые могут иметь запятые или специальные символы. А затем декодируйте его, когда он используется / отображается на любом визуальном носителе.
(запятые становятся% 2C)
У каждого языка должны быть методы для URL-кодирования и декодирования строк.
например, в Java
Я знаю, что это очень общее решение, и оно не может быть идеальным для ситуации, когда пользователь хочет просмотреть содержимое CSV-файла вручную.
источник
Я обычно делаю это в моих процедурах разбора CSV-файлов. Предположим, что переменная 'line' - это одна строка в файле CSV, а все значения столбцов заключены в двойные кавычки. После выполнения следующих двух строк вы получите столбцы CSV в коллекции 'values'.
источник
Самое простое решение, которое я нашел, это то, которое использует LibreOffice:
"
на”
Вы также можете использовать тот, который использует Excel:
"
на""
Обратите внимание, что другие люди рекомендовали сделать только шаг 2, описанный выше, но это не работает со строками, за
"
которыми следует a,
, как в CSV, где вы хотите иметь один столбец со строкойhello",world
, так как CSV будет читать:Который интерпретируется как строка с двумя столбцами:
hello
иworld"
источник
hello",world
поле просто необходимо сохранить как"hello"",world"
, которое можно проанализировать на 100% правильно.источник
Я использовал библиотеку Csvreader, но с ее помощью я получил данные, взорвавшись от запятой (,) в значении столбца.
Поэтому, если вы хотите вставить данные файла CSV, которые содержат запятую (,) в большинстве значений столбцов, вы можете использовать функцию ниже. Ссылка на автора => https://gist.github.com/jaywilliams/385876
источник
Я использовал библиотеку papaParse для анализа файла CSV и получения пар ключ-значение (ключ / заголовок / первая строка значения файла CSV).
Вот пример, который я использую:
https://codesandbox.io/embed/llqmrp96pm
там есть файл dummy.csv для демонстрации разбора CSV.
Я использовал его в ReactionJS, хотя его легко воспроизвести в приложении, написанном на любом языке.
источник
Пример может помочь показать, как запятые могут отображаться в CSV-файле. Создайте простой текстовый файл следующим образом:
Сохраните этот текстовый файл как текстовый файл с суффиксом «.csv» и откройте его в Excel 2000 из Windows 10.
aa, bb, cc, d; d "В представлении электронной таблицы нижняя строка должна выглядеть так, как показано выше, за исключением того, что ниже показана отображаемая запятая вместо точки с запятой между точками". аа, bb, cc, "d, d", это работает даже в Excel
аа, bb, cc, "d, d", это работает даже в Excel 2000 аа, bb, cc, "d, d", это работает даже в Excel 2000 аа, bb, cc, "d, d", это работает даже в Excel 2000
aa, bb, cc, "d, d", это терпит неудачу в Excel 2000 из-за пробела в первой цитате aa, bb, cc, "d, d", это терпит неудачу в Excel 2000 из-за пробела после первой цитаты aa, bb, cc, "d, d", это не удается в Excel 2000 из-за пробела в космосе, первая цитата
aa, bb, cc, "d, d", это работает даже в Excel 2000 даже с пробелами до и после 2-й кавычки. aa, bb, cc, "d, d", это работает даже в Excel 2000 даже с пробелами до и после 2-й кавычки. aa, bb, cc, "d, d", это работает даже в Excel 2000 даже с пробелами до и после 2-й кавычки.
Правило: если вы хотите отобразить запятую в ячейке (поле) файла .csv: «начинайте и заканчивайте поле двойными кавычками, но избегайте пробелов перед первой кавычкой»
источник
Я думаю, что самое простое решение этой проблемы состоит в том, чтобы клиент открыл CSV в Excel, а затем Ctrl + R, чтобы заменить все запятые на любой идентификатор, который вы хотите. Это очень просто для клиента и требует только одного изменения в вашем коде, чтобы прочитать выбранный вами разделитель.
источник
Используйте символ табуляции (\ t) для разделения полей.
источник