Existe-t-il un bon analyseur, réutilisable, qui convertit une chaîne en une hiérarchie de listes?

StackOverflow https://stackoverflow.com/questions/456259

Question

J'aimerais prendre une chaîne telle que celle-ci:

[One, Two[A, B[i, ii, iii, iv], C], Three]

Et convertissez-le en une hiérarchie de listes, de sorte que si j'exécute un code tel que celui-ci:

Console.Write(myList[1][1][2]);

Le résultat sera:

iii

J'espère que c'est une exigence assez commune qu'il existe un code d'analyse simple écrit en C # this.

Faites-moi savoir si ma question pourrait être formulée plus clairement.

Était-ce utile?

La solution

Les balises XML ou JSON sont d'excellentes méthodes pour stocker ce type de choses.

Comme Spence l’a dit - c’est un problème difficile - je ne recommande pas de lancer le vôtre.

Faites défiler le lien JSON vers le bas pour rechercher les implémentations dans la plupart des langues.

Autres conseils

Je devrais y aller avec une expression régulière. Les correspondances et les sous-expressions de sous-chaîne peuvent vous donner la récursivité nécessaire pour obtenir les niveaux de sous-sous -....

Utilisez quelque chose comme /^\[(.+)\]$/ dans preg pour collecter un seul niveau d’éléments. Traitez-le jusqu'à ce que vous ne receviez plus de niveau, expliquez-le après avoir reçu le courage d'une seule série.

Scinder le résultat en ','.

devrait sortir comme

  • [Un, deux [A, B [i, ii, iii, iv], C], trois]
    • Un
    • Deux
    • [A, B [i, ii, iii, iv], C]
      • A
      • B
      • [i, ii, iii, iv]
        • i
        • ii
        • iii
        • iv
      • C
    • Trois

Supprimez enfin les espaces gauche / droite pour obtenir un résultat impeccable.

Vous recherchez des tableaux ou des listes?

Cela serait extrêmement difficile à faire avec des chaînes car vous devez gérer des espaces ou utiliser une virgule dans un élément, etc.

Si vous avez le contrôle sur ce qui est dans cette liste, je vous suggère de vous pencher sur la sérialisation XML ou binaire, qui possède des bibliothèques pour vous y aider.

Ce n’est pas une réponse pratique, mais si vous êtes capable d’utiliser la version bêta de .NET 4.0, vous pouvez vous pencher sur Oslo (et les outils ultérieurs) que Microsoft est en train de développer pour les DSL textuels, qui semble bien répondre exactement à vos besoins.

Mon vote concerne également XML, JSON ou un autre format si vous avez la possibilité de contrôler le format. Mais à défaut, voici une implémentation en Python de l’analyseur parce que je me suis ennuyé.

class ExprParser(object):
current = []
list_stack = []

def __init__(self):
    pass

def parse(self,input):
    for atom in [s.strip() for s in input.split(',')]:
        self.parse_atom(atom)
    return self.current

def do_pushes(self,atom):
    """ Strip off the '[' and push new lists """
    i = 0
    while i < len(atom) and atom[i] == '[':
        self.push()
        i += 1
    return atom[i:]

def do_pops(self,atom):
    """ Pop the lists """
    i = 0
    while i < len(atom) and atom[i] == ']':
        self.pop()
        i += 1

def parse_atom(self,atom):
    push_start = atom.find('[')

    rest = self.do_pushes(atom[push_start:]) if push_start >= 0 else atom

    pop_start = rest.find(']')

    val = rest[:pop_start] if pop_start >= 0 else rest

    self.add(val)

    if pop_start >= 0:
        self.do_pops(rest[pop_start:])

def push(self):
    self.current = []
    self.list_stack.append(self.current)

def pop(self):
    done = self.list_stack.pop()
    self.current = self.list_stack[-1] if self.list_stack else done
    if self.current is not done:
        self.add(done)

def add(self,val):
    self.current.append(val)

Utilisez comme:

parser = ExprParser()
parser.parse('[One, Two[A, B[i, ii, iii, iv], C], Three]')

Pas de traitement des erreurs pour les entrées mal formées.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top