2015-04-26 13 views
5

Próbuję utworzyć coś w rodzaju skryptu poliglota. Nie jest to prawdziwa poliglota, ponieważ w rzeczywistości wymaga wielu języków, chociaż może być "bootstrapowana" przez Shell lub Batch. Ta część nie ma problemu.Powershell: Odczytywanie fragmentu pliku do zmiennej

Część, z którą mam problem, to trochę osadzonego kodu Powershell, który musi być w stanie załadować bieżący plik do pamięci i wyodrębnić pewną sekcję, która jest napisana w jeszcze innym języku, zapisać ją w zmiennej i ostatecznie przekazać go tłumaczowi. Mam system znakowania podobny do XML, którego używam do oznaczania sekcji pliku w sposób, który, mam nadzieję, nie będzie sprzeczny z żadnym innym językiem. Markery wyglądać następująco:

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

te # 's są markery komentarz, ale znaczniki komentarz może być różne rzeczy w zależności od języka sekcji.

Problem polega na tym, że nie mogę znaleźć sposobu na odizolowanie tylko tej części pliku. Mogę załadować cały plik do pamięci, ale nie mogę uzyskać danych między tagami. Tu jest mój bieżący kod:

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

Wszystko próbowałem dotąd wyniki w cały plik jest wysyłany w Contents zamiast po prostu kod między znacznikami. Próbowałem różnych metod ucieczki od symboli używanych w znacznikach, ale zawsze skutkuje to tym samym.

UWAGA: Zastosowanie ^ jest wymagane, ponieważ interpreter najwyższego poziomu jest partii, która odkłada się na wspornikach kątowych i innych przypadkowych rzeczy.

+0

Próbowałaś '$ re = '<{LANGB}><{/LANGB}> (ów?) (*.?)';'? –

+0

To faktycznie zwraca całą zawartość pliku, z wyjątkiem samych znaczników. To znaczy. lang_a # ... język b ... # lang_c – BHarms

+0

Czy jest kilka lub tylko jeden blok? Jeśli jest to tylko jeden, możesz użyć tego samego wyrażenia regularnego, ale z operatorem '-match', a następnie uzyskać dostęp do tekstu za pomocą zmiennej' $ matches [1] ', która jest ustawiona jako wynik' -match'. –

Odpowiedz

5

Ponieważ istnieje tylko jeden blok, można użyć wyrażenia regularnego

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

ale z -match operatora, a następnie uzyskać dostęp do tekstu przy użyciu $matches[1] zmienną, która jest ustawiona w wyniku -match.

Więc po deklaracji regex, użyj

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

Yup. Dodałem też ^^. * Tam, aby upewnić się, że nie został uwzględniony także początek ostatniej linii: '$ re = '(? S)^<{LANGB}^> (. *) ^^. *^<{/LANGB}^>' ;^' – BHarms

+0

Widzę, dodałem tę zmianę. –

Powiązane problemy