2015-04-26 18 views
5

Ich versuche, eine Art von Polyglot-Skript zu erstellen. Es ist kein echtes Polyglott, da es tatsächlich mehrere Sprachen erfordert, obwohl es entweder von Shell oder Batch "bootstrapped" werden kann. Ich habe diesen Teil runter, kein Problem.Powershell: Lesen Sie einen Abschnitt einer Datei in eine Variable

Der Teil, mit dem ich Probleme habe, ist ein wenig eingebetteten Powershell-Code, der in der Lage sein muss, die aktuelle Datei in den Speicher zu laden und einen bestimmten Abschnitt, der in einer anderen Sprache geschrieben ist, zu speichern und schließlich in einen Dolmetscher übergehen. Ich verwende ein XML-ähnliches Tagging-System, mit dem ich Abschnitte der Datei so markieren kann, dass sie hoffentlich nicht mit anderen Sprachen kollidieren. Die Marker wie folgt aussehen:

lang_a_code 
# <{LANGB}> 
    ... code in language B ... 
    ... code in language B ... 
    ... code in language B ... 
# <{/LANGB}> 
lang_c_code 

Die # 's Kommentarmarkierungen sind, aber die Kommentarmarkierungen können verschiedene Dinge sein, abhängig von der Sprache des Abschnitts.

Das Problem, das ich habe, ist, dass ich nicht scheinen kann, einen Weg zu finden, nur diesen Teil der Datei zu isolieren. Ich kann die gesamte Datei in den Speicher laden, aber ich kann das Zeug zwischen den Tags nicht abrufen. Hier ist mein aktueller Code:

@ECHO OFF 
SETLOCAL EnableDelayedExpansion 

powershell -ExecutionPolicy unrestricted -Command^

    $re = '(?m)^<{LANGB}^>(.*)^<{/LANGB}^>';^ 
    $lang_b_code = ([IO.File]::ReadAllText(^'%0^') -replace $re,'$1');^ 
    echo "${re}";^ 
    echo "Contents: ${lang_b_code}"; 

Alles, was ich bisher Ergebnisse in der gesamten Datei versucht habe, Ausgabe in den Contents sein und nicht nur der Code zwischen den Markierungen. Ich habe verschiedene Methoden ausprobiert, um die in den Markern verwendeten Symbole zu umgehen, aber es ergibt sich immer das Gleiche.

HINWEIS: Die Verwendung des ^ ist erforderlich, weil die Top-Level-Interpreter Batch ist, die auf den spitzen Klammern und andere zufällige Dinge auflegt.

+0

Haben Sie versucht, '$ re = '<{LANGB}><{/LANGB}> (s?) (*.?)';'? –

+0

Das gibt tatsächlich den gesamten Inhalt der Datei mit Ausnahme der Markierungen selbst zurück. Ie. lang_a # ... Sprache b ... # lang_c – BHarms

+0

Gibt es mehr oder nur einen Block? Wenn es nur eine ist, können Sie die gleiche Regex verwenden, aber mit "-match" -Operator, und dann auf den Text zugreifen mit <$ matches [1] 'Variable, die als Ergebnis von" match "gesetzt ist. –

Antwort

5

Da es nur ein Block ist, können Sie die regex verwenden

$re = '(?s)^<{LANGB}^>(.*)^^.*^<{/LANGB}^>';^ 

aber mit -match Operator und dann Zugriff auf den Text mit $matches[1] Variable, die als Folge der -match gesetzt.

Also, nach der Regex Deklaration verwenden

[IO.File]::ReadAllText(^'%0^') -match $re;^ 
echo $matches[1]; 
+0

Yup. Außerdem fügte ich ein ^^. * Hinzu, um sicherzustellen, dass der Anfang der letzten Zeile auch nicht enthalten war: '$ re = '(? S)^<{LANGB}^> (. *) ^^. *^<{/LANGB}^>' ; '' – BHarms

+0

Ich sehe, ich habe diese Änderung hinzugefügt. –

Verwandte Themen