Analisador Java CSV com separador de string (multi-caractere)

Existe alguma biblioteca de código aberto Java que ofereça suporte a separadores (delimitadores) de vários caracteres (isto é, String com comprimento> 1) para CSV?

Por definição, CSV = dados separados por vírgulas com um único caractere (‘,’) como delimitador. No entanto, existem muitas outras alternativas de caracteres únicos (por exemplo, tabulação), fazendo com que o CSV defenda os dados “Valores separados por caracteres” (essencialmente, dados DSV: Valores separados por delimitador).

As principais bibliotecas de código aberto Java para CSV (por exemplo, OpenCSV ) suportam virtualmente qualquer caractere como delimitadores, mas não delimitadores de cadeias de caracteres ( multicaracteres ). Então, para dados separados por strings como “|||” não há outra opção além de pré-processar a input para transformar a string em um delimitador de caractere único. A partir de então, os dados podem ser analisados ​​como valores separados por um caractere.

Portanto, seria bom se houvesse uma biblioteca que suportasse nativamente os separadores de string, de modo que nenhum pré-processamento fosse necessário. Isso significaria que o CSV agora representava dados “CharSequence-Separated Values”. 🙂

Essa é uma boa pergunta. O problema não era óbvio para mim até que eu olhei para os javadocs e percebi que o opencsv só suporta um caractere como um separador, não uma string ….

Aqui estão algumas soluções sugeridas (Exemplos no Groovy podem ser convertidos em java).

Ignorar campos intermediários implícitos

Continue a usar o OpenCSV, mas ignore os campos vazios. Obviamente, isso é uma fraude, mas funcionará bem para analisar dados bem comportados.

CSVParser csv = new CSVParser((char)'|') String[] result = csv.parseLine('J||Project report||"F, G, I"||1') assert result[0] == "J" assert result[2] == "Project report" assert result[4] == "F, G, I" assert result[6] == "1" 

ou

  CSVParser csv = new CSVParser((char)'|') String[] result = csv.parseLine('J

Project report

“F, G, I”

1′) assert result[0] == “J” assert result[3] == “Project report” assert result[6] == “F, G, I” assert result[9] == “1”

Role seu próprio

Use o método de tokenizer Java String.

  def result = 'J

Project report

“F, G, I”

1′.tokenize(‘

‘) assert result[0] == “J” assert result[1] == “Project report” assert result[2] == “\”F, G, I\”” assert result[3] == “1”

A desvantagem dessa abordagem é que você perde a capacidade de ignorar caracteres de aspas ou de separar os separadores.

Atualizar

Em vez de pré-processar os dados, alterando seu conteúdo, por que não combinar as duas abordagens acima em um processo de duas etapas:

  1. Use o “rolar seu próprio” para primeiro validar os dados. Divida cada linha e prove que ela contém o número de solicitações de campos.
  2. Use a abordagem “campo ignorando” para analisar os dados validados, assegurando-se de que o número correto de campos foi especificado.

Não muito eficiente, mas possivelmente mais fácil que escrever seu próprio analisador de CSV 🙂

Experimente o opencsv .

Ele faz tudo que você precisa, incluindo (e especialmente) manipulando delimitadores embutidos dentro de valores entre aspas (por exemplo, "a,b", "c" interpreta como ["a,b", "c"] )

Eu usei com sucesso e gostei.

Editado:

Como o opencsv manipula apenas separadores de caractere único, você pode contornar isso assim:

 String input; char someCharNotInInput = '|'; String delimiter = "abc"; // or whatever input.replaceAll(delimiter, someCharNotInInput); new CSVReader(input, someCharNotInInput); // etc // Put it back into each value read value.replaceAll(someCharNotInInput, delimiter); // in case it's inside delimiters 
    Intereting Posts