Frage

Ich möchte so etwas wie eine Konfigurationsdatei analysieren:

[KEY:Value]     
    [SUBKEY:SubValue]

Jetzt habe ich mit einem angefangen StreamReader, Zeilen in Zeichenarrays umwandeln, als ich dachte, dass es einen besseren Weg geben muss.Deshalb bitte ich Sie, bescheidener Leser, mir zu helfen.

Eine Einschränkung besteht darin, dass es in einer Linux/Mono-Umgebung funktionieren muss (1.2.6 um genau zu sein).Ich habe nicht die neueste Version 2.0 (von Mono), daher versuchen Sie, die Sprachfunktionen auf C# 2.0 oder C# 1.0 zu beschränken.

War es hilfreich?

Lösung

Ich habe darüber nachgedacht, aber ich werde kein XML verwenden.Ich werde dieses Zeug von Hand schreiben, und die manuelle Bearbeitung von XML tut mir im Gehirn weh.:')

Hast Du Dir angesehen YAML?

Sie profitieren von den Vorteilen von XML ohne den ganzen Aufwand.Es wird in der Ruby-Community häufig für Dinge wie Konfigurationsdateien, vorgefertigte Datenbankdaten usw. verwendet

Hier ist ein Beispiel

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

Es scheint eine zu geben C#-Bibliothek hier, was ich nicht persönlich benutzt habe, aber Yaml ist ziemlich einfach, also "wie schwer kann es sein?" :-)

Ich würde sagen, es ist besser, als ein eigenes Ad-hoc-Format zu erfinden (und sich mit Parser-Fehlern zu befassen).

Andere Tipps

Ich habe mir neulich fast genau dieses Problem angesehen: Dieser Artikel Die Tokenisierung von Zeichenfolgen ist genau das, was Sie brauchen.Sie möchten Ihre Token wie folgt definieren:

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

Der Artikel erklärt es ziemlich gut.Von da an fangen Sie einfach an, Token nach Belieben aufzufressen.

Profi-Tipp:Für ein LL(1)-Parser (lesen:einfach), Token können kein Präfix teilen.Wenn Sie haben abc als Zeichen kann man es nicht haben ace als Zeichen

Notiz:Der Artikel fehlt die | Charaktere in seinen Beispielen werfen sie einfach hinein.

Es gibt eine weitere YAML-Bibliothek für .NET welches sich in der Entwicklung befindet.Derzeit unterstützt es das Lesen von YAML-Streams und wurde unter Windows und Mono getestet.Die Schreibunterstützung wird derzeit implementiert.

Die Verwendung einer Bibliothek ist fast immer dem Erstellen einer eigenen Bibliothek vorzuziehen.Hier ist eine kurze Liste von „Oh, das werde ich nie brauchen/darüber habe ich nicht nachgedacht“-Punkte, die Ihnen später noch in den Sinn kommen werden:

  • Fluchtcharaktere.Was ist, wenn Sie Folgendes wünschen:im Schlüssel oder ] im Wert?
  • Das Escape-Zeichen entkommen.
  • Unicode
  • Mischung aus Tabulatoren und Leerzeichen (siehe die Probleme mit der Leerzeichen-sensitiven Syntax von Python)
  • Umgang mit verschiedenen Rückgabezeichenformaten
  • Umgang mit Syntaxfehlerberichten

Wie andere bereits vorgeschlagen haben, scheint YAML die beste Wahl zu sein.

Sie können auch einen Stapel verwenden und einen Push/Pop-Algorithmus verwenden.Dieses entspricht den offenen/schließenden Tags.

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";
    }

Sie können wahrscheinlich eine Anpassung vornehmen, damit Sie den Inhalt Ihrer Datei lesen können.Auch reguläre Ausdrücke sind eine gute Idee.

Meiner Meinung nach wäre es besser, eine XML-basierte Konfigurationsdatei zu verwenden, da es bereits .NET-Klassen gibt, die die Informationen relativ einfach für Sie lesen und speichern können.Gibt es einen Grund, warum dies nicht möglich ist?

@Bernard: Es stimmt, dass die manuelle Bearbeitung von XML mühsam ist, aber die Struktur, die Sie präsentieren, sieht XML bereits sehr ähnlich.

Dann hat ja da eine gute Methode.

@Gishu

Nachdem ich die maskierten Zeichen berücksichtigt hatte, lief mein regulärer Ausdruck tatsächlich etwas langsamer als mein handgeschriebener rekursiver Parser von oben nach unten, und das ohne die Verschachtelung (Verknüpfung von Unterelementen mit ihren übergeordneten Elementen) und die Fehlermeldung, die der handgeschriebene Parser hatte.

Der reguläre Ausdruck war etwas schneller zu schreiben (obwohl ich ein wenig Erfahrung mit Handparsern habe), aber das ohne gute Fehlerberichterstattung.Sobald Sie das hinzufügen, wird es etwas schwieriger und länger.

Ich finde es auch einfacher, die Absicht des handgeschriebenen Parsers zu verstehen.Hier ist zum Beispiel ein Codeausschnitt:

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

Unabhängig vom beibehaltenen Format wäre die Verwendung eines Regex die schnellste Möglichkeit zum Parsen.In Ruby wären es wahrscheinlich ein paar Codezeilen.

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

Mit diesen beiden erhalten Sie den Wert und den Unterwert in der ersten Gruppe.Sehen Sie sich MSDN an, um zu erfahren, wie Sie einen regulären Ausdruck mit einer Zeichenfolge abgleichen.

Das sollte jeder in seiner Katze haben.Die Tage vor Regex scheinen wie eine Eiszeit.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top