Найкращий спосіб обробки файлів з розмежуванням


16

Отже, як правило, у файлі CSV використовується символ із комою та символом повернення, оскільки це розділювачі поля та рядка.

Це стикається з очевидними проблемами з текстом, який може містити обидва ці символи.

Очевидно, що є варіанти (уникнути їх), але як люди впораються з цим? Використовуєте різні символи - труби чи тильди? Врятуватися від них? Не використовуйте файли з розмежуванням, адже це 2010 рік, і тепер у нас є XML?

Потрібні хоча б зусилля на гідний шанс не бачити проблем.

(Просто для того, щоб бути зрозумілим, це питання з цікавості, а не чогось більш твердого - це те, з чим я стикався час і знову, граючи з даними, завжди його обминаю, але це нормально трохи, добре, брудно, і цікавився, який досвід інших людей).


Подумайте над тим, як використовувати CSV - з ним приємно і легко (див. Відповіді на загальні правила виходу), але це не настільки настільки оперативно, як це має бути - якщо ви просто спілкуєтесь зі своїми програмами, це добре, але якщо ви Хочете імпортувати в інше місце, це стає трохи дивним, оскільки різні програми підкоряються різним правилам виходу.
Майкл Коне

@Michael - абсолютно. Проблема в тому, що вона настільки всюди присутня, що ви майже завжди стикаєтеся з часом, коли це дуже спокусливий варіант, а для багатьох старих систем - це єдиний варіант.
Джон Хопкінс

Зрілі бібліотеки існують на багатьох мовах (безумовно, загальних) для читання та запису файлів з обмеженими символами. Вони впораються з більшості будь-якої ситуації. Написання власного аналізатора CSV, здається, є звичайним анти-шаблоном.
квентин-зірин

Відповіді:


13

За даними Вікіпедії :

Поля із вбудованими комами повинні бути укладені у символи подвійної лапки.

І ще:

Поля із вбудованими символами з подвійною цитатами повинні бути вкладені в символи подвійної цитати, а кожен із вбудованих символів подвійної цитати повинен бути представлений парою символів з подвійною цитатами.

Я не знаю, хто це вигадав, але це ефективно показує, що зрештою вам потрібно втекти. Це єдине міцне рішення. Все інше - це просто клейка стрічка на вершині клейкої стрічки: можливо, вона працює і зараз, але зрештою ви натрапите на випадок, коли вам потрібен виняток, за винятком винятку, і це не займе багато часу, перш ніж ваш грязьовий правила спосіб складніший, ніж просте рішення про втечу символів.

Здається, що творці CSV спершу намагалися уникнути уникнення коми, створивши спеціальний синтаксис з подвійним котируванням, який дозволив зберегти коми, але потім хтось теж захотів зберегти символи з подвійним цитуванням, тому їм довелося втекти в цьому пункті - весело використовуючи подвійна цитата як символ втечі. Якби вони вирішили втекти належним чином, синтаксис був би простішим.


3
Що має бути, а що .. часто відрізняється :)
Tim Post

Я думаю, що рішення цілком нормальне. Для простих даних CSV працює нормально, для складних даних необхідне цитування, і втеча слідів "з" "назад до BASIC.
Ернеллі

1
@Ernelli: Тепер, коли я думаю про це більше, це насправді може бути розумним компромісом між читабельністю людини та простотою. Проблема втечі полягає в тому, що це виглядає непривабливо для людей , навіть якщо комп'ютер банально розбирає. Таким чином, резервування вхідних рядків лише для рідкісних випадків ("поля із вбудованими символами з подвійною цитатами") дає результат, який зазвичай виглядає цілком зрозумілим для людини. Це хороше рішення, якщо припустити, що коси в іменах полів частіше використовуються, ніж подвійні лапки у назвах полів.
Joonas Pulakka

2

Я припускаю, що у вас є щось подібне:

Foo,Baz,,,"Foo,Baz"

Якщо рядки, що містять роздільник, не цитуються та не використовуються, у вас немає реального надійного способу розбору файлу.

Однак ви можете вивчити дані для розбору та зробити висновки на зразок:

  • Поплавці, відокремлені комами, слід розглядати як рядок
  • Якщо рядок до або після цього містить менше роздільників, пропустіть їх розбір і введіть його
  • Поводитись "як"

Вам потрібно написати аналізатор, щоб обробляти подібні речі, але це не повинно бути складним.

На мій досвід, імпорт масивних смітників із чогось подібного Excel завжди призводить до того, що потрібно повернутися назад і переглянути деякі дивні кульки. Ваше завдання полягає в тому, щоб дати вашій програмі тільки досить здорового глузду в відношенні даних , так що він не робить божевільні вставки. Потім перегляньте те, що було зареєстровано, і вимийте / промийте / повторіть.

Я колись обробляв внутрішній FAQ для невеликої компанії, яка використовувала всі робочі станції Ubuntu. Частина поширених запитань давала "ярлики оболонок", і мені це було розмежовано. Ну, відповіді також були типово обмеженими (тобто grep foo | щось), а не цитувались і не уникали. Я відчуваю цей біль :)


2

З CSV до певного моменту нічого поганого

CSV добре працює для жорстко визначених даних, які навряд чи змінять формат і не проводять багато сюрпризів на аналізаторі одержувача.

Ось зручний список великих ґатухів:

  1. Уникнення "" s всередині "" s (поле містить роздільник поля)
  2. містить "CRLF" (поле містить роздільник рядків)
  3. Unicode (базовий текстовий формат може бути недостатнім)
  4. Різні лінійні термінатори для різних ОС (це CR або CRLF або LF або NUL?)
  5. Вбудовані коментарі (рядок з префіксом #, //, -,; тощо)
  6. Управління версіями (остання версія файлу містить більш-менш поля)
  7. Розмежування між NULL та порожніми даними (, "" є порожнім, але ,, null?)

Ви можете звернутися до цього за допомогою заголовка метаданих, який описує, як слід розбирати поля, але тоді ви можете просто використовувати XML. Саме завдяки такому безладному формату CSV було винайдено. Підхід XML просто здається надто важким для того, що, зважаючи на це, може бути простою проблемою.

Популярною альтернативою є стратегія "дивний роздільник символів". Це дозволяє вирішити безліч проблем, що витікають вище, тому що ви використовуєте щось на зразок | (труба) символ для розмежування поля та CRLF для припинення запису. Це не обходить проблему з багаторядковим полем (якщо ви не використовуєте лічильник поля), але ви отримуєте чітко відформатовані лінії для людей.

Загалом, якщо ви просто шукаєте простий спосіб обробки такого файлу, то в світі Java ви можете просто кинути на нього OpenCSV . Таким чином ви абстрагуєте всі проблеми в усталених рамках.


2

CSV все ще є дійсним форматом у багатьох ситуаціях, тим більше, що клієнтові все-таки найпростіший спосіб записувати дані, які потрібно імпортувати у вашу програму. Мало хто з наших клієнтів любить мати справу з XML, можливо, тому що він дуже багатослівний і має всі ці «страшні» кутові дужки. Їм набагато простіше обернути мізки навколо простого списку предметів, розділених узгодженим символом, а також погоджуються, що той самий символ не буде дозволений у вмісті поля.

З цього приводу, вам все одно належить правильно обробляти дані та перевіряти ситуації, коли вони використовують недійсні символи. Я почав використовувати FileHelpers для мого розбору CSV.


1

я звичайно дотримуюся стандарту і рятуюся від них. у більшості мов програмування є хороша вбудована підтримка або хороша бібліотека.

це залежить від ситуації, який формат буде використовуватися і CSV - розумний формат для обміну простими структурами формату даних.


0

Забудьте про CSV, використовуйте JSON . Легко писати, легко розбирати. XML - це так 2005 рік .


6
і є така ж проблема, коли ви хочете використовувати символ, який є частиною формату JSON (наприклад, {або,)
Salandur

Саландур: Зовсім не! Існують точні правила, як втекти! Але {і, навіть не потрібно бігти, бо всередині рядок, вони неоднозначні!
користувач281377

1
Ну і добре, але я не пригадую, щоб у програмі "Експортувати в JSON" функція ":)" Бувають випадки, коли вам доведеться розбирати непарні речі, аби лише перевести їх у більш приємний формат.
Тим Пост

1
А JSON просто такий геніальний для передачі близько мільйона об'єктів такої ж форми. Зачекайте.
Френк Шірар

1
JSON не пропонує поліпшення щодо CSV щодо цього питання і вкрай не вистачає сумісності з багатьма додатками (як уже зазначалося, не можна імпортувати чи експортувати з Office, SQL БД тощо). JSON чудово підходить для внутрішніх легких операцій на стороні клієнта, але XML набагато краще для передачі даних між додатками.
Дан Диплом

0

Зазвичай, я вважаю, що я отримую TSV (значення, розділені на вкладки), а не файл CSV, перетягуйте файл у Emacs і дивіться, який з небагатьох символів він НІКОЛИ не використовує ($ зазвичай тут хороший вибір), а потім я конвертую всі вкладки в $.

Звідти GNU AWK можна сказати використовувати $ як роздільник поля, а Боб - ваш дядько.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.