Il modo migliore per gestire i file delimitati

16

Quindi in genere un file CSV utilizza una virgola e il carattere di ritorno come delimitatori di campo e linea.

Questo porta a ovvi problemi con il testo che può contenere entrambi questi caratteri.

Ovviamente ci sono delle opzioni lì (sfuggirle) ma come le persone gestiscono questo? Usa caratteri diversi - pipe o tildas? Fuggirli? Non utilizzare file delimitati, dopotutto è il 2010 e ora abbiamo XML?

Guardare almeno lo sforzo per una buona possibilità di non vedere i problemi.

(Giusto per essere chiari, questa è una domanda per curiosità piuttosto che qualcosa di più solido - è qualcosa che ho incontrato di volta in volta giocando con i dati, l'ho sempre aggirato ma normalmente si sente un po ', bene , sporco, e mi chiedevo quale fosse l'esperienza degli altri).

    
posta Jon Hopkins 14.12.2010 - 12:52
fonte

7 risposte

13

In base a Wikipedia :

Fields with embedded commas must be enclosed within double-quote characters.

E inoltre:

Fields with embedded double-quote characters must be enclosed within double-quote characters, and each of the embedded double-quote characters must be represented by a pair of double-quote characters.

Non so chi l'abbia inventato, ma in realtà dimostra che alla fine devi fuggire. È l'unica soluzione solida. Tutto il resto è solo nastro adesivo sopra il nastro adesivo: forse funziona per ora, ma alla fine ti imbatterai in un caso in cui hai bisogno di un'eccezione ad eccezione di un'eccezione, e non ci vorrà molto prima che il tuo fango delle regole è molto più complesso di una semplice soluzione di escape character.

Sembra che i creatori di CSV abbiano tentato per la prima volta di evitare le virgole evocando una sintassi speciale a due virgolette, che permetteva di salvare virgole, ma poi qualcuno voleva salvare anche caratteri a doppia virgola, quindi dovevano scappare a quel punto - usando stranamente la doppia citazione come personaggio di fuga. Se avessero deciso di fuggire correttamente, in primo luogo, la sintassi sarebbe stata più semplice ora.

    
risposta data 14.12.2010 - 13:11
fonte
2

Suppongo che tu abbia qualcosa del genere:

Foo,Baz,,,"Foo,Baz"

Se le stringhe che contengono il delimitatore non sono quotate o sfuggite, non hai un modo affidabile di reale per analizzare il file.

Puoi, comunque, esaminare i dati per analizzare e trarre conclusioni come:

  • I float separati da virgola devono essere trattati come una stringa
  • Se la riga precedente o successiva contiene meno delimitatori, salta l'analisi di questa riga e la registra
  • Tratta "mi piace"

Devi scrivere un parser per gestire cose del genere, ma non deve essere complicato.

In base alla mia esperienza, l'importazione di dump massicci da qualcosa di simile a Excel comporta sempre il dover tornare indietro e rivedere alcuni oddball. La tua sfida è dare al tuo programma solo abbastanza buon senso riguardo ai dati in modo che non faccia un inserto pazzo. Quindi rivedi ciò che è stato registrato e lava / risciacqua / ripeti.

Una volta ho gestito una FAQ interna per una piccola azienda che utilizzava tutte le workstation Ubuntu. Una parte delle FAQ conteneva 'scorciatoie da shell' e mi arrivava delimitata da pipe. Bene, anche le risposte erano in genere delimitate da pipe (ad esempio grep foo | qualcosa) e non quotate o fuggite. Sento quel dolore:)

    
risposta data 14.12.2010 - 13:08
fonte
2

Niente di male con CSV fino a un punto

CSV funziona bene per dati rigidamente definiti che è improbabile che cambi formato e non susciti molte sorprese sul parser dei destinatari.

Ecco un elenco pratico dei grandi trucchi:

  1. Escaping "" s all'interno di "" s (il campo contiene delimitatore di campo)
  2. "" s contenente CRLF (il campo contiene delimitatore di riga)
  3. Unicode (il formato di testo sottostante potrebbe essere insufficiente)
  4. Terminatori di linea diversi per sistemi operativi diversi (è CR o CRLF o LF o NUL?)
  5. Commenti in linea (riga preceduta da #, //, -,; ecc.)
  6. Gestione delle versioni (l'ultima versione del file contiene più o meno campi)
  7. Differenzia tra NULL e dati vuoti (, "", è vuoto ma , è nullo?)

Potresti avvicinarti a questo con un'intestazione di meta-dati che descrive come devono essere analizzati i campi, ma allora puoi anche usare XML. È a causa di questo tipo di caos CSV a forma libera che è stato inventato. L'approccio XML sembra troppo pesante per quello che potrebbe, a prima vista, essere un problema semplice.

Un'alternativa popolare è la strategia del "delimitatore di caratteri". Questo risolve un sacco di problemi di escape sopra perché si usa qualcosa come un | (pipe) per la delimitazione del campo e un CRLF per la terminazione del record. Questo non risolve il problema del campo multi-linea (a meno che non si usi un contatore di campo) ma si ottengono linee ben formattate per gli umani.

Nel complesso, se stai solo cercando un modo semplice per gestire questo tipo di file, nel mondo Java potresti semplicemente lanciare OpenCSV a questo. In questo modo estrai tutti i problemi in una struttura consolidata.

    
risposta data 14.12.2010 - 14:19
fonte
2

CSV è ancora un formato valido in molte situazioni, soprattutto perché deve ancora essere il modo più semplice per un cliente di scrivere dati che devono essere importati nella tua applicazione. Pochi dei nostri clienti amano trattare XML, forse perché è molto prolisso e ha tutte quelle parentesi angolari "spaventose". È molto più semplice per loro avvolgere il cervello attorno a un semplice elenco di elementi separati da un carattere concordato, e anche concordare che lo stesso personaggio non sarà consentito nei contenuti di un campo.

Detto questo, devi ancora gestire correttamente l'input e verificare le situazioni in cui utilizzano caratteri non validi. Ho iniziato a utilizzare FileHelpers per le mie esigenze di analisi CSV.

    
risposta data 14.12.2010 - 14:56
fonte
1

di solito sono fedele allo standard e li sfuggo. nella maggior parte dei linguaggi di programmazione c'è un buon supporto integrato o una buona libreria disponibile.

dipende dalla situazione in cui verrà utilizzato il formato e CSV è un formato ragionevole per lo scambio di strutture di formato dati semplici.

    
risposta data 14.12.2010 - 12:58
fonte
0

Dimentica CSV, usa JSON . Facile da scrivere, facile da analizzare. XML è così 2005 .

    
risposta data 14.12.2010 - 12:57
fonte
0

Di solito, quello che mi ritrovo a fare è ottenere un TSV (valori separati da tabulazioni) piuttosto che un file CSV, trascinare il file in Emacs e vedere quale di alcuni caratteri non comuni non usa MAI ($ è solitamente una buona scelta in giro qui), e poi converto tutte le schede in $.

Da lì, GNU AWK può dire di usare $ come separatore di campi, e Bob è tuo zio.

    
risposta data 14.12.2010 - 16:57
fonte

Leggi altre domande sui tag