Eu tenho o seguinte tipo de string
var string = "'string, duppi, du', 23, lala"
Quero dividir a string em uma matriz em cada vírgula, mas apenas as vírgulas fora das aspas simples.
Não consigo descobrir a expressão regular correta para a divisão ...
string.split(/,/)
vai me dar
["'string", " duppi", " du'", " 23", " lala"]
mas o resultado deve ser:
["string, duppi, du", "23", "lala"]
Existe uma solução para vários navegadores?
javascript
regex
split
Hans
fonte
fonte
Respostas:
aviso Legal
Atualização de 01-12-2014: A resposta abaixo funciona apenas para um formato muito específico de CSV. Como corretamente apontado pelo DG nos comentários, esta solução NÃO se encaixa na definição de CSV da RFC 4180 e também NÃO se encaixa no formato MS Excel. Esta solução simplesmente demonstra como é possível analisar uma linha CSV (não padrão) de entrada que contém uma mistura de tipos de string, em que as strings podem conter aspas e vírgulas com escape.
Uma solução CSV não padrão
Como austincheney aponta corretamente, você realmente precisa analisar a string do início ao fim se quiser lidar adequadamente com strings entre aspas que podem conter caracteres de escape. Além disso, o OP não define claramente o que é realmente uma "string CSV". Primeiro, devemos definir o que constitui uma string CSV válida e seus valores individuais.
Dado: Definição de "string CSV"
Para o propósito desta discussão, uma "string CSV" consiste em zero ou mais valores, onde vários valores são separados por uma vírgula. Cada valor pode consistir em:
Regras / Notas:
'that\'s cool'
.\'
em valores entre aspas simples.\"
em valores entre aspas duplas.Encontrar:
Uma função JavaScript que converte uma string CSV válida (conforme definido acima) em uma matriz de valores de string.
Solução:
As expressões regulares usadas por esta solução são complexas. E (IMHO) todos os regexes não triviais devem ser apresentados em modo de espaçamento livre com muitos comentários e recuos. Infelizmente, o JavaScript não permite o modo de espaçamento livre. Assim, as expressões regulares implementadas por esta solução são apresentadas primeiro na sintaxe regex nativa (expressa usando a prática do Python:
r'''...'''
sintaxe de string de várias linhas bruta).Primeiro, aqui está uma expressão regular que valida se uma string CVS atende aos requisitos acima:
Regex para validar uma "string CSV":
Se uma string corresponder à regex acima, então essa string é uma string CSV válida (de acordo com as regras declaradas anteriormente) e pode ser analisada usando a seguinte regex. O seguinte regex é então usado para corresponder a um valor da string CSV. É aplicado repetidamente até que não sejam encontradas mais correspondências (e todos os valores tenham sido analisados).
Regex para analisar um valor de uma string CSV válida:
Observe que há um valor de caso especial que esta regex não corresponde - o último valor quando esse valor está vazio. Este caso especial de "último valor vazio" é testado e tratado pela função js que se segue.
Função JavaScript para analisar string CSV:
Exemplo de entrada e saída:
Nos exemplos a seguir, as chaves são usadas para delimitar o
{result strings}
. (Isso ajuda a visualizar espaços iniciais / finais e strings de comprimento zero.)Notas Adicionais:
Esta solução requer que a string CSV seja "válida". Por exemplo, valores sem aspas não podem conter barras invertidas ou aspas, por exemplo, a seguinte string CSV NÃO é válida:
Isso não é realmente uma limitação porque qualquer sub-string pode ser representada como um valor entre aspas simples ou duplas. Observe também que esta solução representa apenas uma definição possível para: "Valores separados por vírgula".
Edit: 2014-05-19: isenção de responsabilidade adicionada. Edit: 2014-12-01: isenção de responsabilidade movida para o topo.
fonte
"field one", "field two", "a ""final"" field containing two double quote marks"
Não testei a resposta de Trevor Dixon nesta página, mas é uma resposta que aborda a definição de CSV da RFC 4180.Solução RFC 4180
Isso não resolve a string em questão, pois seu formato não está em conformidade com RFC 4180; a codificação aceitável está escapando de aspas duplas. A solução abaixo funciona corretamente com arquivos CSV d / l de planilhas do Google.
ATUALIZAÇÃO (3/2017)
Analisar uma única linha seria errado. De acordo com a RFC 4180, os campos podem conter CRLF, o que fará com que qualquer leitor de linha quebre o arquivo CSV. Esta é uma versão atualizada que analisa a string CSV:
RESPOSTA ANTIGA
(Solução de linha única)
E para se divertir, veja como você cria CSV a partir do array:
fonte
Gramática PEG (.js) que lida com exemplos RFC 4180 em http://en.wikipedia.org/wiki/Comma-separated_values :
Teste em http://jsfiddle.net/knvzk/10 ou https://pegjs.org/online .
Baixe o analisador gerado em https://gist.github.com/3362830 .
fonte
Tive um caso de uso muito específico em que queria copiar células do Planilhas Google para meu aplicativo da web. As células podem incluir aspas duplas e caracteres de nova linha. Usando copiar e colar, as células são delimitadas por caracteres de tabulação e células com dados ímpares são colocadas entre aspas. Tentei esta solução principal, o artigo vinculado usando regexp, Jquery-CSV e CSVToArray. http://papaparse.com/ É o único que funcionou fora da caixa. Copiar e colar funciona perfeitamente com o Planilhas Google, com opções de detecção automática padrão.
fonte
Gostei da resposta do FakeRainBrigand, mas ela contém alguns problemas: Não consegue lidar com espaços em branco entre aspas e vírgulas e não suporta 2 vírgulas consecutivas. Tentei editar sua resposta, mas minha edição foi rejeitada por revisores que aparentemente não entenderam meu código. Aqui está minha versão do código do FakeRainBrigand. Também há um violino: http://jsfiddle.net/xTezm/46/
fonte
As pessoas pareciam ser contra o RegEx por isso. Por quê?
Aqui está o código. Eu também fiz um violino .
fonte
Adicionando mais um à lista, porque eu acho que todos os itens acima não são "KISS" o suficiente.
Este usa regex para encontrar vírgulas ou novas linhas enquanto pula os itens citados. Esperançosamente, isso é algo que os noobies podem ler por conta própria. A
splitFinder
regexp tem três funções (dividida por a|
):,
- encontra vírgulas\r?\n
- encontra novas linhas, (potencialmente com retorno de carro se o exportador for bom)"(\\"|[^"])*?"
- pula qualquer coisa entre aspas, porque vírgulas e novas linhas não importam aqui. Se houver uma cotação de escape\\"
no item cotado, ela será capturada antes que uma cotação final possa ser encontrada.fonte
Id, Name, Age 1, John Smith, 65 2, Jane Doe, 30
como posso analisar com base nas colunas que eu especificar?[{Id: 1, Name: "John Smith", Age: 65}, {Id: 2, Name: "Jane Doe", Age: 30}]
Se você pode ter seu delimitador de aspas duplas, então esta é uma duplicata do código JavaScript para analisar dados CSV .
Você pode traduzir todas as aspas simples para aspas duplas primeiro:
... ou você pode editar o regex nessa questão para reconhecer aspas simples em vez de aspas duplas:
No entanto, isso pressupõe certa marcação que não está clara em sua pergunta. Por favor, esclareça quais podem ser todas as várias possibilidades de marcação, de acordo com meu comentário sobre sua pergunta.
fonte
Minha resposta presume que sua entrada é um reflexo do código / conteúdo de fontes da web onde caracteres de aspas simples e duplas são totalmente intercambiáveis, desde que ocorram como um conjunto de correspondência sem escape.
Você não pode usar regex para isso. Na verdade, você precisa escrever um micro analisador para analisar a string que deseja dividir. Eu irei, por causa desta resposta, chamar as partes citadas de suas strings como sub-strings. Você precisa caminhar especificamente pela corda. Considere o seguinte caso:
Nesse caso, você não tem absolutamente nenhuma ideia de onde uma sequência secundária começa ou termina simplesmente analisando a entrada para um padrão de caractere. Em vez disso, você deve escrever uma lógica para tomar decisões sobre se um caractere de aspas é usado como um caractere de aspas, se ele próprio não está cotado e se o caractere de aspas não segue um escape.
Não vou escrever esse nível de complexidade de código para você, mas você pode ver algo que escrevi recentemente que tem o padrão de que você precisa. Este código não tem nada a ver com vírgulas, mas é um micro-analisador válido o suficiente para você seguir escrevendo seu próprio código. Observe a função asifixo do seguinte aplicativo:
https://github.com/austincheney/Pretty-Diff/blob/master/fulljsmin.js
fonte
Para complementar esta resposta
Se você precisar analisar aspas escapadas com outra citação, exemplo:
Você pode usar
fonte
"jjj "" kkk""","123"
sem regexp, legível, de acordo com https://en.wikipedia.org/wiki/Comma-separated_values#Basic_rules
fonte
Ao ler o arquivo CSV em uma string, ele contém valores nulos entre as strings, então tente com \ 0 linha por linha. Funciona para mim.
fonte
Eu também enfrentei o mesmo tipo de problema ao analisar um arquivo CSV.
O arquivo contém um endereço de coluna que contém o ','.
Depois de analisar esse arquivo CSV para JSON, recebo o mapeamento incompatível das chaves ao convertê-lo em um arquivo JSON.
Usei Node.js para analisar o arquivo e bibliotecas como baby parse e csvtojson .
Exemplo de arquivo -
Enquanto eu estava analisando diretamente sem usar a análise de bebê em JSON, eu estava conseguindo:
Então, escrevi um código que remove a vírgula (,) com qualquer outro delimitador em cada campo:
A função retornada pode ser passada para a biblioteca csvtojson e, portanto, o resultado pode ser usado.
Agora você pode obter a saída como:
fonte
De acordo com esta postagem do blog , esta função deve fazer isso:
Você o chamaria assim:
Esse tipo de quebra-cabeça funciona, mas parece que alguns dos elementos têm espaços antes deles.
fonte
"'string, duppi, du', 23, lala"
["'string"," duppi"," du'"," 23"," lala"]
"'"
para'"'
e vice-versa.'"string, duppi, du", 23, lala'
resulta em:['"string',' duppi'.' du"',' 23',' lala']
Expressões regulares para o resgate! Essas poucas linhas de código lidam com campos devidamente citados com vírgulas, aspas e novas linhas incorporadas com base no padrão RFC 4180.
A menos que declarado em outro lugar, você não precisa de uma máquina de estado finito. A expressão regular trata a RFC 4180 de maneira adequada graças a lookbehind positivo, lookbehind negativo e lookahead positivo.
Clone / faça download do código em https://github.com/peterthoeny/parse-csv-js
fonte
Além da excelente e completa resposta do ridgerunner , pensei em uma solução alternativa muito simples para quando seu back-end executa PHP.
Adicionar este arquivo PHP para backend do seu domínio (digamos:
csv.php
)Agora adicione esta função ao seu kit de ferramentas JavaScript (deve ser revisado um pouco para fazer crossbrowser, eu acredito).
Custará uma chamada Ajax, mas pelo menos você não duplicará o código nem incluirá qualquer biblioteca externa.
Ref: http://php.net/manual/en/function.str-getcsv.php
fonte
Você pode usar papaparse.js como o exemplo abaixo:
Não se esqueça de incluir papaparse.js na mesma pasta.
fonte