Question

Je veux analyser un fichier de configuration, comme ceci :

[KEY:Value]     
    [SUBKEY:SubValue]

Maintenant, j'ai commencé avec un StreamReader, convertissant les lignes en tableaux de caractères, alors que je pensais qu'il devait y avoir une meilleure façon.Je vous demande donc, humble lecteur, de m'aider.

Une restriction est qu'il doit fonctionner dans un environnement Linux/Mono (1.2.6 pour être exact).Je n'ai pas la dernière version 2.0 (de Mono), alors essayez de limiter les fonctionnalités du langage à C# 2.0 ou C# 1.0.

Était-ce utile?

La solution

J'y ai réfléchi, mais je ne vais pas utiliser XML.Je vais écrire ce genre de choses à la main, et l'édition manuelle de XML me fait mal au cerveau.:')

As-tu regardé YAML?

Vous bénéficiez des avantages du XML sans toutes les douleurs et souffrances.Il est largement utilisé dans la communauté Ruby pour des éléments tels que les fichiers de configuration, les données de base de données pré-préparées, etc.

voici un exemple

customer:
  name: Orion
  age: 26
  addresses:
    - type: Work
      number: 12
      street: Bob Street
    - type: Home
      number: 15
      street: Secret Road

Il semble y avoir un Bibliothèque C# ici, que je n'ai pas utilisé personnellement, mais Yaml est assez simple, alors "à quel point cela peut-il être difficile?" :-)

Je dirais qu'il est préférable d'inventer votre propre format ad hoc (et de gérer les bugs de l'analyseur)

Autres conseils

Je regardais presque exactement ce problème l'autre jour : Cet article sur la tokenisation des chaînes est exactement ce dont vous avez besoin.Vous souhaiterez définir vos jetons comme quelque chose comme :

@"(?&ltlevel>\s) | " +
@"(?&ltterm>[^:\s]) | " +
@"(?&ltseparator>:)"

L'article explique très bien cela.À partir de là, vous commencez simplement à manger des jetons comme bon vous semble.

Astuce :Pour un analyseur LL(1) (lire:facile), les jetons ne peuvent pas partager un préfixe.Si tu as abc en guise de gage, vous ne pouvez pas avoir ace comme un jeton

Note:L'article manque le | Les personnages de ses exemples, jetez-les simplement.

Il y a une autre bibliothèque YAML pour .NET qui est en cours de développement.À l'heure actuelle, il prend en charge la lecture des flux YAML et a été testé sur Windows et Mono.Le support en écriture est actuellement en cours de mise en œuvre.

Il est presque toujours préférable d’utiliser une bibliothèque plutôt que de créer la vôtre.Voici une liste rapide des points « Oh, je n'aurai jamais besoin de ça/je n'y ai pas pensé » qui finiront par vous mordre plus tard :

  • Personnages en fuite.Et si vous voulez un :dans la clé ou ] dans la valeur ?
  • Échapper au caractère d'échappement.
  • Unicode
  • Mélange de tabulations et d'espaces (voir les problèmes avec la syntaxe sensible aux espaces blancs de Python)
  • Gestion de différents formats de caractères de retour
  • Gestion des rapports d'erreurs de syntaxe

Comme d’autres l’ont suggéré, YAML semble être votre meilleur choix.

Vous pouvez également utiliser une pile et utiliser un algorithme push/pop.Celui-ci correspond aux balises d’ouverture/fermeture.

public string check()
    {
        ArrayList tags = getTags();


        int stackSize = tags.Count;

        Stack stack = new Stack(stackSize);

        foreach (string tag in tags)
        {
            if (!tag.Contains('/'))
            {
                stack.push(tag);
            }
            else
            {
                if (!stack.isEmpty())
                {
                    string startTag = stack.pop();
                    startTag = startTag.Substring(1, startTag.Length - 1);
                    string endTag = tag.Substring(2, tag.Length - 2);
                    if (!startTag.Equals(endTag))
                    {
                        return "Fout: geen matchende eindtag";
                    }
                }
                else
                {
                    return "Fout: geen matchende openeningstag";
                }
            }
        }

        if (!stack.isEmpty())
        {
            return "Fout: geen matchende eindtag";
        }            
        return "Xml is valid";
    }

Vous pouvez probablement vous adapter pour pouvoir lire le contenu de votre fichier.Les expressions régulières sont également une bonne idée.

Il me semble que vous feriez mieux d'utiliser un fichier de configuration basé sur XML, car il existe déjà des classes .NET qui peuvent lire et stocker les informations pour vous relativement facilement.Y a-t-il une raison pour laquelle cela n'est pas possible ?

@Bernard : Il est vrai que l'édition manuelle de XML est fastidieuse, mais la structure que vous présentez ressemble déjà beaucoup à XML.

Alors oui, il y a une bonne méthode là-bas.

@Gishu

En fait, une fois que j'ai pris en compte les caractères échappés, mon expression régulière s'est déroulée légèrement plus lentement que mon analyseur récursif écrit à la main et c'est sans l'imbrication (liaison des sous-éléments à leurs parents) et le rapport d'erreur de l'analyseur écrit à la main.

L'expression régulière était légèrement plus rapide à écrire (même si j'ai un peu d'expérience avec les analyseurs manuels), mais sans un bon rapport d'erreurs.Une fois que vous ajoutez cela, cela devient légèrement plus difficile et plus long à faire.

Je trouve également que l'analyseur manuscrit est plus facile à comprendre.Par exemple, voici un extrait de code :

private static Node ParseNode(TextReader reader)
{
    Node node = new Node();
    int indentation = ParseWhitespace(reader);
    Expect(reader, '[');
    node.Key = ParseTerminatedString(reader, ':');
    node.Value = ParseTerminatedString(reader, ']');
}

Quel que soit le format persistant, l'utilisation d'une Regex serait le moyen d'analyse le plus rapide.En Ruby, ce serait probablement quelques lignes de code.

\[KEY:(.*)\] 
\[SUBKEY:(.*)\]

Ces deux-là vous obtiendraient la valeur et la sous-valeur dans le premier groupe.Consultez MSDN pour savoir comment faire correspondre une expression régulière à une chaîne.

C'est quelque chose que tout le monde devrait avoir dans son chat.Les jours pré-Regex ressembleraient à l’ère glaciaire.

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