Melhor maneira de lidar com arquivos delimitados


16

Normalmente, um arquivo CSV usa vírgula e o caractere de retorno como delimitadores de campo e linha.

Isso ocorre com problemas óbvios com o texto, que pode conter esses dois caracteres.

Obviamente, existem opções lá (escapando-as), mas como as pessoas lidam com isso? Use caracteres diferentes - cachimbos ou tildas? Escapar deles? Não use arquivos delimitados, afinal é 2010 e agora temos XML?

Procurando pelo menos esforço por uma chance decente de não encontrar problemas.

(Só para esclarecer, essa é uma questão de curiosidade, e não de algo mais sólido - é algo que eu lembro várias vezes de brincar com dados, sempre contorná-los, mas normalmente parece um pouco, bem, sujo, e se perguntou qual era a experiência de outras pessoas).


Pense com cuidado sobre o uso de CSV - é agradável e fácil de lidar (consulte as respostas para regras de escape comuns), mas não é tão interoperável quanto deveria - se você está apenas se comunicando com seus próprios programas, tudo bem, mas se você quer importar para outro lugar, fica um pouco estranho porque programas diferentes obedecem a regras de escape diferentes.
Michael Kohne

@ Michael - Absolutamente. A questão, porém, é que é tão onipresente que você quase sempre apresenta momentos em que é uma opção muito tentadora e, no caso de muitos sistemas mais antigos, é a única opção.
Jon Hopkins

Bibliotecas maduras existem em muitos idiomas (certamente os mais comuns) para ler e escrever arquivos delimitados por caracteres. Eles vão lidar com quase todas as situações. Escrever o próprio analisador de CSV parece ser um tipo comum de antipadrão.
Quentin-starin

Respostas:


13

De acordo com a Wikipedia :

Os campos com vírgulas incorporadas devem ser colocados entre caracteres de aspas duplas.

E além disso:

Os campos com caracteres de aspas duplas incorporados devem ser colocados entre caracteres de aspas duplas e cada um dos caracteres de aspas duplas incorporados deve ser representado por um par de caracteres de aspas duplas.

Não sei quem inventou isso, mas mostra efetivamente que, eventualmente, você precisa escapar. É a única solução sólida. Todo o resto é apenas fita adesiva em cima da fita adesiva: talvez funcione por enquanto, mas, eventualmente, você encontrará um caso em que precisa de uma exceção à exceção de uma exceção, e não demora muito para o seu jogo de regras é muito mais complexo do que uma solução simples de caractere de escape.

Parece que os criadores de CSV tentaram evitar o escape de vírgulas criando uma sintaxe especial entre aspas duplas, o que permitia salvar vírgulas, mas então alguém queria salvar caracteres de aspas duplas também, então eles tiveram que escapar naquele momento - usando o aspas duplas como um caractere de escape. Se eles tivessem decidido escapar adequadamente em primeiro lugar, a sintaxe seria mais simples agora.


3
O que deveria ser e o que é .. muitas vezes difere :) #
445 Tim Tim

Eu acho que a solução está bem. Para dados simples, o CSV funciona bem; para dados complexos, é necessário citar dados, e escapar "com" "dos traços de volta ao BASIC.
Ernelli

1
@ Ernelli: Agora que penso mais sobre isso, pode ser realmente um compromisso razoável entre legibilidade e simplicidade. O problema de escapar é que parece feio para os seres humanos , mesmo que seja trivial para o computador analisar. Assim, reservar escapes apenas para casos raros ("campos com caracteres de aspas duplas incorporadas") produz resultados que geralmente parecem legíveis por humanos. Essa é uma boa solução, supondo que vírgulas nos nomes dos campos sejam usadas com mais frequência do que aspas duplas nos nomes dos campos.
Joonas Pulakka

2

Suponho que você tenha algo parecido com isto:

Foo,Baz,,,"Foo,Baz"

Se as seqüências que contêm o delimitador não são citadas ou escapadas, você não tem uma maneira realmente confiável de analisar o arquivo.

No entanto, você pode examinar os dados para analisar e tirar conclusões como:

  • Flutuadores separados por vírgula devem ser tratados como uma string
  • Se a linha antes ou depois dela contiver menos delimitadores, pule a análise dessa linha e registre-a
  • Tratar como "

Você precisa escrever um analisador para lidar com coisas assim, mas não precisa ser complicado.

Na minha experiência, a importação de lixões maciços de algo como o Excel sempre resulta em ter que voltar e revisar alguns excêntricos. Seu desafio é dar ao seu programa apenas bom senso suficiente sobre os dados para que ele não faz uma inserção de louco. Em seguida, revise o que foi registrado e lave / enxágue / repita.

Uma vez, lidei com uma FAQ interna para uma pequena empresa que usava todas as estações de trabalho Ubuntu. Uma parte do FAQ forneceu 'atalhos de shell' e veio a mim delimitado por canal. Bem, as respostas também foram tipicamente delimitadas por pipe (isto é, grep foo | something) e não foram citadas ou escapadas. Eu sinto essa dor :)


2

Nada de errado com o CSV até certo ponto

O CSV funciona bem para dados rigidamente definidos que dificilmente mudarão de formato e não causam muitas surpresas no analisador de destinatários.

Aqui está uma lista útil das grandes dicas:

  1. Escapando "" s dentro de "" s (o campo contém delimitador de campo)
  2. "" s contendo CRLFs (o campo contém delimitador de linha)
  3. Unicode (o formato do texto subjacente pode ser insuficiente)
  4. Terminadores de linha diferentes para sistemas operacionais diferentes (é CR ou CRLF ou LF ou NUL?)
  5. Comentários embutidos (linha prefixada com #, //, -,; etc)
  6. Gerenciamento de versão (a versão mais recente do arquivo contém mais ou menos campos)
  7. Diferenciar entre dados nulos e vazios (, "" está vazio, mas ,, é nulo?)

Você pode abordar isso com um cabeçalho de metadados que descreve como os campos devem ser analisados, mas também pode usar apenas XML. É por causa desse tipo de bagunça CSV de forma livre que foi inventada. A abordagem XML parece muito pesada para o que poderia, em face disso, ser um problema simples.

Uma alternativa popular é a estratégia "delimitador de caracteres estranhos". Isso contorna muitos dos problemas de escape acima, porque você usa algo como um | caractere (pipe) para delimitação de campo e um CRLF para finalização de registro. Isso não contorna a questão do campo de várias linhas (a menos que você use um contador de campo), mas você obtém linhas bem formatadas para humanos.

No geral, se você está procurando uma maneira simples de lidar com esse tipo de arquivo, no mundo Java, você pode simplesmente jogar o OpenCSV nele. Dessa forma, você abstrai todos os problemas em uma estrutura estabelecida.


2

O CSV ainda é um formato válido em muitas situações, especialmente porque ainda deve ser a maneira mais fácil para um cliente gravar dados que precisam ser importados para o seu aplicativo. Poucos de nossos clientes gostam de lidar com XML, talvez porque seja muito detalhado e possua todos esses colchetes angulares "assustadores". É muito mais simples para eles envolverem seus cérebros em torno de uma lista simples de itens separados por um personagem acordado e também concordam que o mesmo personagem não será permitido no conteúdo de um campo.

Dito isso, você ainda precisa manipular a entrada corretamente e verificar as situações em que eles usam caracteres inválidos. Comecei a usar o FileHelpers para minhas necessidades de análise de CSV.


1

Eu costumo manter o padrão e escapar deles. Na maioria das linguagens de programação, há um bom suporte interno ou uma boa biblioteca disponível.

depende da situação em que formato será usado e o CSV é um formato razoável para trocar estruturas simples de formato de dados.


0

Esqueça o CSV, use JSON . Fácil de escrever, fácil de analisar. XML é tão 2005 .


6
e tem o mesmo problema quando você deseja usar um caractere que faz parte do formato JSON (como {ou,)
Salandur

Salandur: Nem um pouco! Existem regras exatas de como escapar! Mas {e, nem precisam ser escapados, porque por dentro são cordas, elas não são ambíguas!
user281377

1
Muito bem, mas não me lembro do excel ter um recurso "Exportar para JSON" :) Há momentos em que você precisa analisar coisas estranhas, apenas para colocá-las em um formato mais agradável.
Tim Post

1
E o JSON é totalmente brilhante para passar um milhão de objetos da mesma forma. Oh espere.
Frank Shearar

1
O JSON não oferece nenhuma melhoria em relação ao CSV em relação a essa questão e carece de interoperabilidade crucial com muitos aplicativos (como foi mencionado, não é possível importar ou exportar do Office, SQL DBs etc.). O JSON é ótimo para operações internas leves do lado do cliente, mas o XML é muito melhor para a transmissão de dados entre aplicativos.
Dan Diplo

0

Geralmente, o que me vejo fazendo é obter um TSV (valores separados por tabulação) em vez de um arquivo CSV, puxar o arquivo para o Emacs e ver qual dos poucos caracteres incomuns NUNCA usa ($ geralmente é uma boa opção por aqui), e depois converto todas as guias para $.

A partir daí, o GNU AWK pode ser instruído a usar $ como separador de campos, e Bob é seu tio.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.