Najlepszy sposób obsługi plików rozdzielanych

16

Tak więc zwykle plik CSV używa przecinka i znaku powrotu jako ograniczników pól i linii.

Powoduje to oczywiste problemy z tekstem, który może zawierać oba te znaki.

Oczywiście istnieją opcje (ucieczka od nich), ale jak ludzie sobie z tym radzą? Używać różnych znaków - rur lub tyld? Uciekniesz im? Nie używaj plików rozdzielanych, w końcu to 2010, a teraz mamy XML?

Szukam przynajmniej wysiłku, aby uzyskać przyzwoitą szansę na nie dostrzeżenie problemów.

(Żeby było jasne, jest to pytanie z ciekawości, a nie z czegoś bardziej solidnego - to coś, z czym borykam się raz po raz, bawiąc się danymi, zawsze sobie z tym radzę, ale zwykle jest trochę brudny, i zastanawiałem się, jakie były doświadczenia innych ludzi).

Jon Hopkins
źródło
Zastanów się dobrze nad użyciem CSV - jest przyjemny i łatwy w obsłudze (zobacz odpowiedzi na często spotykane reguły ucieczki), ale nie jest tak łatwy do współpracy, jak powinien - jeśli tylko komunikujesz się ze swoimi programami, jest w porządku, ale jeśli chcę zaimportować gdzie indziej, robi się to nieco dziwne, ponieważ różne programy przestrzegają różnych reguł ucieczki.
Michael Kohne
@Michael - Absolutnie. Problem polega jednak na tym, że jest tak wszechobecny, że prawie zawsze wymyślisz czasy, kiedy jest to bardzo kusząca opcja, aw przypadku wielu starszych systemów jest to jedyna opcja.
Jon Hopkins
Dojrzałe biblioteki istnieją w wielu językach (z pewnością powszechnych) do odczytu i zapisu plików rozdzielanych znakami. Poradzą sobie w każdej sytuacji. Pisanie własnego parsera CSV wydaje się być powszechnym rodzajem anty-wzorca.
quentin-starin

Odpowiedzi:

13

Według Wikipedii :

Pola z osadzonymi przecinkami muszą być ujęte w znaki podwójnego cudzysłowu.

A ponadto:

Pola z osadzonymi znakami podwójnego cudzysłowu muszą być zawarte w znakach podwójnego cudzysłowu, a każdy z osadzonych znaków cudzysłowu musi być reprezentowany przez parę znaków cudzysłowu.

Nie wiem, kto to wymyślił, ale skutecznie pokazuje, że w końcu musisz uciec. To jedyne solidne rozwiązanie. Cała reszta to po prostu taśma klejąca na taśmie klejowej: może na razie działa, ale w końcu wpadniesz na przypadek, w którym potrzebujesz wyjątku od wyjątku, i nie zajmie to dużo czasu jest o wiele bardziej skomplikowane niż proste rozwiązanie znaków ucieczki.

Wygląda na to, że twórcy CSV najpierw starali się unikać przecinków, wymyślając specjalną składnię z podwójnym cudzysłowem, która umożliwiała zapisywanie przecinków, ale potem ktoś też chciał zapisać znaki cudzysłowu, więc w tym momencie musiał uciec - zabawnie podwójny cytat jako znak ucieczki. Gdyby w pierwszej kolejności postanowili uciec właściwie, składnia byłaby teraz prostsza.

Joonas Pulakka
źródło
3
Co powinno być, a co jest… często się różni :)
Tim Post
Myślę, że rozwiązanie jest w porządku. W przypadku prostych danych CSV działa dobrze, w przypadku złożonych danych konieczne jest cytowanie i unikanie śladów „z” „z powrotem do BASIC.
Ernelli,
1
@Ernelli: Teraz, gdy się nad tym zastanowię, może to być rozsądny kompromis między czytelnością dla ludzi a prostotą. Problem polegający na ucieczce polega na tym, że wygląda brzydko dla ludzi , nawet jeśli komputer jest trywialny . Zatem rezerwowanie znaków ucieczki tylko w rzadkich przypadkach („pola z osadzonymi znakami podwójnego cudzysłowu”) daje wyniki, które zwykle wyglądają dość czytelnie dla ludzi. Jest to dobre rozwiązanie, zakładając, że przecinki w nazwach pól są częściej używane niż cudzysłowy w nazwach pól.
Joonas Pulakka
2

Zakładam, że masz coś takiego:

Foo,Baz,,,"Foo,Baz"

Jeśli ciągi zawierające ogranicznik nie są cytowane ani nie są poprzedzane znakami ucieczki, nie ma naprawdę wiarygodnego sposobu analizowania pliku.

Możesz jednak zbadać dane do przeanalizowania i wyciągnąć wnioski, takie jak:

  • Pływaki oddzielone przecinkami należy traktować jako ciąg
  • Jeśli wiersz przed nim lub po nim zawiera mniej ograniczników, pomiń parsowanie tego wiersza i zaloguj go
  • Traktuj „jak”

Musisz napisać analizator składni do obsługi takich rzeczy, ale nie musi to być skomplikowane.

Z mojego doświadczenia wynika, że ​​importowanie ogromnych zrzutów z czegoś takiego jak Excel zawsze powoduje, że muszę wrócić i sprawdzić niektóre dziwne kulki. Twoim wyzwaniem jest, aby dać swój program tylko tyle zdrowego rozsądku odnośnie danych tak, że nie robi się szalony wkładkę. Następnie sprawdź, co zostało zarejestrowane i umyj / spłucz / powtórz.

Kiedyś zajmowałem się wewnętrznym FAQ dla małej firmy, która korzystała ze wszystkich stacji roboczych Ubuntu. Część często zadawanych pytań zawierała „skróty powłoki” i przyszła do mnie rozdzielana potokami. Cóż, odpowiedzi były również zwykle rozdzielane potokami (tj. Grep foo | coś) i nie były cytowane ani unikane. Czuję ten ból :)

Tim Post
źródło
2

Do pewnego momentu nie ma nic złego w CSV

CSV działa dobrze w przypadku sztywno zdefiniowanych danych, które prawdopodobnie nie zmienią formatu i nie wywołują wielu niespodzianek na parserze odbiorcy.

Oto przydatna lista wielkich gotch:

  1. Ucieczka „” w „s” (pole zawiera ogranicznik pola)
  2. „” s zawierające CRLF (pole zawiera separator wiersza)
  3. Unicode (podstawowy format tekstu może być niewystarczający)
  4. Różne terminatory linii dla różnych systemów operacyjnych (czy CR, CRLF, LF czy NUL?)
  5. Komentarze wbudowane (wiersz poprzedzony znakiem #, //, -, itp.)
  6. Zarządzanie wersjami (najnowsza wersja pliku zawiera mniej lub więcej pól)
  7. Rozróżnianie NULL i pustych danych („”, jest puste, ale ,, jest zerowe?)

Możesz do tego podejść za pomocą nagłówka metadanych, który opisuje, w jaki sposób pola powinny zostać przeanalizowane, ale równie dobrze możesz po prostu użyć XML. To z powodu tego rodzaju swobodnego bałaganu CSV, że został wynaleziony. Podejście XML wydaje się po prostu zbyt ciężkie, aby na pierwszy rzut oka mógł stanowić prosty problem.

Popularną alternatywą jest strategia „dziwnego ogranicznika znaków”. To omija wiele problemów ucieczki powyżej, ponieważ używasz czegoś takiego jak | (potok) znak do rozdzielania pól i CRLF do zakończenia rekordu. Nie rozwiązuje to problemu pola wieloliniowego (chyba że używasz licznika pól), ale dostajesz ładnie sformatowane linie dla ludzi.

Ogólnie rzecz biorąc, jeśli szukasz prostego sposobu obsługi tego rodzaju plików, w świecie Java możesz po prostu rzucić na nie OpenCSV . W ten sposób wyodrębniasz wszystkie problemy w ustalone ramy.

Gary Rowe
źródło
2

CSV nadal jest poprawnym formatem w wielu sytuacjach, zwłaszcza, że ​​wciąż musi być najprostszym sposobem dla klienta na zapis danych, które należy zaimportować do aplikacji. Niewielu naszych klientów lubi zajmować się XML, być może dlatego, że jest bardzo gadatliwy i ma wszystkie te „przerażające” nawiasy. O wiele łatwiej jest owijać mózgi wokół prostej listy przedmiotów oddzielonych uzgodnioną postacią, a także zgodzić się, że ta sama postać nie będzie dozwolona w zawartości pola.

To powiedziawszy, nadal musisz poprawnie obsługiwać dane wejściowe i sprawdzać sytuacje, w których używają nieprawidłowych znaków. Zacząłem używać FileHelpers do moich potrzeb analizy CSV.

Dave
źródło
1

zwykle trzymam się standardu i uciekam od nich. w większości języków programowania jest dostępne dobre wbudowane wsparcie lub dobra biblioteka.

zależy to od sytuacji, który format zostanie użyty, a CSV jest rozsądnym formatem do wymiany prostych struktur formatu danych.

Salandur
źródło
0

Zapomnij o CSV, użyj JSON . Łatwy do napisania, łatwy do analizy. XML jest taki 2005 .

użytkownik 281377
źródło
6
i ma ten sam problem, gdy chcesz użyć znaku, który jest częścią formatu JSON (np. {lub,)
Salandur,
Salandur: Wcale nie! Istnieją dokładne zasady ucieczki! Ale {i nawet nie trzeba uciekać, ponieważ wewnątrz są sznurki, nie są one dwuznaczne!
user281377,
1
Cóż, dobrze, ale nie przypominam sobie, aby Excel miał funkcję „Eksportuj do JSON” :) Są chwile, kiedy trzeba przeanalizować dziwne rzeczy, choćby po to, aby uzyskać bardziej przyjemny format.
Tim Post
1
A JSON jest tak genialny, że przekazuje około miliona obiektów o tym samym kształcie. Zaczekaj.
Frank Shearar,
1
JSON nie oferuje żadnej poprawy w stosunku do CSV w odniesieniu do tego pytania i bardzo brakuje interoperacyjności z wieloma aplikacjami (jak wspomniano, nie można importować ani eksportować z Office, SQL DBs itp.). JSON doskonale nadaje się do wewnętrznych, lekkich operacji po stronie klienta, ale XML jest znacznie lepszy do przesyłania danych między aplikacjami.
Dan Diplo,
0

Zazwyczaj to, co robię, to pobieranie TSV (wartości rozdzielane tabulatorami) zamiast pliku CSV, ściąganie pliku do Emacsa i sprawdzanie, którego z kilku niezwykłych znaków NIGDY nie używa ($ jest tu zwykle dobrym wyborem), a następnie przekonwertuję wszystkie zakładki na $.

Stamtąd można powiedzieć GNU AWK, aby używał $ jako separatora pól, a Bob jest twoim wujem.

John R. Strohm
źródło