Pergunta

Estou analisando uma string delimitada, algo da ordem de

abc

Mas este é um exemplo muito simples, e a análise de dados delimitados pode ser complexa;por exemplo

1,"Seu algoritmo simples falha",Verdadeiro

explodiria sua implementação ingênua de string.Split em pedaços.Existe algo que eu possa usar/roubar/copiar e colar livremente que ofereça uma solução relativamente à prova de balas para analisar texto delimitado?.NET, plox.

Atualizar: Eu decidi ir com o TextFieldParser, que faz parte da pilha de novidades do VB.NET escondidas em Microsoft.VisualBasic.DLL.

Foi útil?

Solução

Eu uso isso para ler um arquivo

string filename = @textBox1.Text;
string[] fields;
string[] delimiter = new string[] {"|"};
using (Microsoft.VisualBasic.FileIO.TextFieldParser parser =
       new Microsoft.VisualBasic.FileIO.TextFieldParser(filename)) {
    parser.Delimiters = delimiter;
    parser.HasFieldsEnclosedInQuotes = false;

    while (!parser.EndOfData) {
        fields = parser.ReadFields();
        //Do what you need
    }
}

Tenho certeza que alguém aqui pode transformar isso para analisar uma string que está na memória.

Outras dicas

Uma biblioteca muito completa pode ser encontrada aqui: Ajudantes de arquivos

Não conheço nenhuma estrutura, mas uma máquina de estado simples funciona:

  • Estado 1:Leia todos os caracteres até encontrar um " ou um ,
    • No caso de um ":Mover para o estado 2
    • No caso de um,:Mover para o estado 3
    • Em caso de final de arquivo:Mover para o estado 4
  • Estado 2:Leia todos os caracteres até encontrar um "
    • No caso de um ":Mover para o estado 1
    • No caso de final do arquivo:Mude para o estado 4 ou sinalize um erro devido a uma string não terminada
  • Estado 3:Adicione o buffer atual à matriz de saída, mova o cursor para frente, atrás de e de volta ao estado 1.
  • Estado 4:este é o estado final, não faz nada exceto retornar a matriz de saída.

Como

var elements = new List<string>();
var current = new StringBuilder();
var p = 0;

while (p < internalLine.Length) {
    if (internalLine[p] == '"') {
        p++;

        while (internalLine[p] != '"') {
            current.Append(internalLine[p]);
            p++;
        }

        // Skip past last ',
        p += 2;
    }
    else {
        while ((p < internalLine.Length) && (internalLine[p] != ',')) {
            current.Append(internalLine[p]);
            p++;
        }

        // Skip past ,
        p++;
    }

    elements.Add(current.ToString());
    current.Length = 0;
}

Existem algumas boas respostas aqui: Dividir uma string ignorando as seções entre aspas

Você pode reformular sua pergunta para algo mais preciso (por exemplo, Qual trecho de código ou biblioteca posso usar para analisar dados CSV no .NET?).

Para fazer um plug sem vergonha, estou trabalhando há algum tempo em uma biblioteca chamada fotelo (Formatted Text Loader) que uso para analisar rapidamente grandes quantidades de texto com base em delimitador, posição ou regex.Para uma string rápida é um exagero, mas se você estiver trabalhando com toras ou grandes quantidades, pode ser exatamente o que você precisa.Ele funciona com base em um modelo de arquivo de controle semelhante ao SQL*Loader (uma espécie de inspiração por trás dele).

Antes tarde do que nunca (adicione à integridade do SO):

http://www.codeproject.com/KB/database/CsvReader.aspx

Este aqui é uma regra.

GJ

Estou pensando que uma estrutura genérica precisaria especificar entre duas coisas:1.Quais são os caracteres delimitadores.2.Sob que condições esses caracteres não contam (como quando estão entre aspas).

Acho que seria melhor escrever uma lógica personalizada sempre que você precisar fazer algo assim.

A maneira mais simples é dividir a string em uma matriz de caracteres e procurar seus determinantes de string e dividir o caractere.

Deve ser relativamente fácil fazer teste de unidade.

Você pode envolvê-lo em um método de extensão semelhante ao método .Spilt básico.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top