2008-08-17 16 views
9

Ich möchte eine Konfigurationsdatei sorta Sache zu analysieren, etwa so:Die beste Methode der Textdateianalyse in C#?

[KEY:Value]  
    [SUBKEY:SubValue] 

Jetzt begann ich mit einem StreamReader, Linien in Zeichen-Arrays konvertieren, wenn ich dachte, es muss doch einen besseren Weg geben. Ich bitte Sie, demütiger Leser, mir zu helfen.

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

Antwort

12

Ich dachte darüber nach, aber ich werde nicht XML verwenden. Ich werde dieses Zeug mit der Hand schreiben, und die Bearbeitung von XML macht mein Gehirn weh. : ')

Haben Sie sich YAML angesehen?

Sie erhalten die Vorteile von XML ohne all die Schmerzen und Leiden. Es wird ausführlich in der Ruby-Community für Dinge wie Konfigurationsdateien, vorgefertigte Datenbankdaten, etc. verwendet

hier ein Beispiel

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

Es erscheint ein C# library here zu sein, die ich nicht persönlich in Anspruch genommen haben, aber Yaml ist ziemlich einfach, also "wie schwer kann es sein?":-)

Ich würde sagen, es zu erfinden Ihre eigenen Ad-hoc-Format (und den Umgang mit Parser Bugs)

0

Es scheint mir, dass Sie besser eine XML-basierte Konfigurationsdatei verwenden würden, da es bereits .NET-Klassen gibt, die die Informationen für Sie relativ einfach lesen und speichern können. Gibt es einen Grund, dass dies nicht möglich ist?

@Bernard: Es ist wahr, dass Handbearbeitung von XML mühsam ist, aber die Struktur, die Sie präsentieren, sieht XML sehr ähnlich.

Dann ja, hat eine gute Methode dort.

0

Sie können auch einen Stapel verwenden und einen Push/Pop-Algorithmus verwenden. Dieser passt auf offene/schließende 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 anpassen, damit Sie den Inhalt Ihrer Datei lesen können. Reguläre Ausdrücke sind auch eine gute Idee.

4

Ich sah fast genau dieses Problem neulich: this article auf Zeichenfolge Tokenizing ist genau das, was Sie brauchen. Sie werden Ihre Tokens als etwas wie definieren wollen:

Der Artikel macht einen ziemlich guten Job, es zu erklären. Von dort fängst du an, Token zu essen, wie du es für richtig hältst.

Protip: Für eine LL(1) parser (lesen: einfach), Tokens können kein Präfix teilen. Wenn Sie abc als Token haben, können Sie ace nicht als Token verwenden

Hinweis: Der Artikel fehlt die | Zeichen in seinen Beispielen, einfach werfen sie in.

1

vorzuziehen ist eine Bibliothek verwenden fast immer bevorzugt ist Ihre eigenen Rollen. Hier ist eine kurze Liste von „Oh, ich werde nie brauchen das/ich habe nicht darüber, dass“ Punkte, die kommen werden am Ende zu beißen später auf der ganzen Linie.

  • Escaping Zeichen Was ist, wenn Sie eine wollen: im Schlüssel oder ] in dem Wert?
  • Escape-Zeichen
  • Unicode
  • Mix aus Tabs und Leerzeichen (siehe die Probleme mit Python Leerraum empfindlichen Syntax)
  • Umgang mit unterschiedlichen Rückgabezeichenformate
  • Syntaxfehler Handhabung

Wie andere berichtet haben vorgeschlagen, sieht YAML wie Ihr bestes Gebot.

-1

Unabhängig vom beibehaltenen Format wäre die Verwendung eines Regex der schnellste Weg zum Parsen. In Ruby wären es wahrscheinlich ein paar Zeilen Code.

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

Diese beiden würden Sie den Wert und SubValue in der ersten Gruppe erhalten. Informieren Sie sich in MSDN darüber, wie eine Regex mit einer Zeichenfolge verglichen wird.

Dies ist etwas, was jeder in seiner Katze haben sollte. Pre-Regex Tage würden wie die Eiszeit aussehen.

0

@Gishu

Eigentlich, wenn ich für Escape-Zeichen meine regex als meine Hand geschrieben von oben nach unten rekursive Parser etwas langsamer lief hatte untergebracht und das ohne die Verschachtelung (Verknüpfung Unterpunkte zu ihren Eltern) und Fehler der Berichterstattung Handgeschriebener Parser hatte.

Die Regex war ein bisschen schneller zu schreiben (obwohl ich ein bisschen Erfahrung mit Handparsern habe), aber das ist ohne gute Fehlermeldung. Sobald Sie hinzufügen, wird es etwas härter und länger zu tun.

Ich finde auch die Hand geschrieben Parser leichter zu verstehen, die Absicht von. Zum Beispiel, hier ist das ein Ausschnitt aus dem 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, ']'); 
} 
1

Es gibt another YAML library for .NET, die in der Entwicklung. Momentan unterstützt es das Lesen von YAML-Streams und wurde unter Windows und Mono getestet. Schreibunterstützung wird derzeit implementiert.

Verwandte Themen