weltfrieden: ini-Files per Regex komplett einlesen

Hallo zusammen,

ich programmiere gerade in C# ein Tool, um ini-Files auszuwerten. Als zusätzliche Hürde habe ich mir vorgenommen, den INI-Parser selbst zu programmieren.

ini-Files haben folgende Struktur:

[sektions-titel]
name=value
name0=value0
name1=value1

[sektions-titel0]
name=value
name0=value0
name1=value1

Klar muss das mit regulären Ausdrücken gemacht werden.
Ich habe auch schon folgenden RegEx zusammen:

(?<SectionName>[[^]]+])\n(?<NameValue>(?<Name>[^=]+)=(?<Value>[^=\n]+\n))+

Leider matcht dieser nur die ersten zwei Zeilen einer jeder Sektion. Obwohl hinten ein + steht.
Vielleicht ist es doch ein eher kleine Sache, die ich falsch mache, doch ich sehe sie gerade nicht. Wie muss der RegEx aussehen, damit er die komplette ini einlesen kann? (Die Sache mit den auskommentierten Zeilen muss ich danach auch noch machen)

Grüße
weltfrieden

  1. Tach!

    ich programmiere gerade in C# ein Tool, um ini-Files auszuwerten. Als zusätzliche Hürde habe ich mir vorgenommen, den INI-Parser selbst zu programmieren.
    Klar muss das mit regulären Ausdrücken gemacht werden.

    Nein, dieser Zwang besteht nicht. Ich würde das zeilenweise durchgehen und nach diversen Merkmalen untersuchen. Dabei kaönnen reguläre Ausdrücke verwendet werden, aber nicht für alle Tests. Ein Test wären leere Zeilen mit beliebig vielen Whitespace. Dazu kann ein RegExp helfen, aber einfacher ist ein Trim() mit anschließender Prüfung auf die Länge 0. So ein Trim kannst du auf jede Zeile anwenden, dann werden auch unbeabsichtigte Einrückungen und abschließende Whitespace gleich korrigiert. Der nächste Test prüft auf das Kommentarzeichen am Anfang. Weiter gehts es mit [ am Anfang und ] am Ende. Hier kann auch eine Regexp-Prüfung auf unerlaubte Zeichen erfolgen, wenn du das für erforderlich hältst. Und so weiter und so fort.

    Ich habe auch schon folgenden RegEx zusammen:
    (?<SectionName>[[^]]+])\n(?<NameValue>(?<Name>[^=]+)=(?<Value>[^=\n]+\n))+
    Leider matcht dieser nur die ersten zwei Zeilen einer jeder Sektion. Obwohl hinten ein + steht.

    Unter PHP nachgebildet trifft es bei mir die erste Sektion und die letzte passende Name-Value-Zeile, also je nach abschließendem Zeilenumbruch die letzte oder die vorletzte. Dazu ist es sinnvoll, die Daten eindeutig zu gestalten, sonst sieht man nicht, was nun konkret matcht.

    Das + heißt, dass das Muster mehrfach vorkommen darf. Das hat meines Erachtens keinen Einfluss auf die Häufigkeit im Ergebnis. Es müsste ja dann zwar nur ein Element für den SectionName aber eine Liste für NameValue im Ergebnis enthalten sein. Das ergibt dann eine Ungleichbehandlung für benannte Gruppen.

    dedlfix.

    1. Tach!

      (?<SectionName>[[^]]+])\n(?<NameValue>(?<Name>[^=]+)=(?<Value>[^=\n]+\n))+
      Das + heißt, dass das Muster mehrfach vorkommen darf. Das hat meines Erachtens keinen Einfluss auf die Häufigkeit im Ergebnis. Es müsste ja dann zwar nur ein Element für den SectionName aber eine Liste für NameValue im Ergebnis enthalten sein. Das ergibt dann eine Ungleichbehandlung für benannte Gruppen.

      Korrektur: Groups und Captures sind immer Collections, auch wenn immer nur ein Vorkommen gesucht werden soll. Damit getestet ergibt, dass die Name-Value-Gruppen gefunden werden, aber an der nächsten Sektion nicht Halt gemacht wird.

      dedlfix.