2015-04-26 14 views
5

Sto provando a creare una specie di script poliglotta. Non è un vero poliglotta perché richiede effettivamente più linguaggi, anche se può essere "riavviato" da Shell o Batch. Ho questa parte senza problemi.PowerShell: leggere una sezione di un file in una variabile

La parte con cui ho problemi è un po 'di codice Powershell incorporato, che deve essere in grado di caricare il file corrente in memoria ed estrarre una determinata sezione scritta in un'altra lingua, memorizzarla in una variabile e infine passarlo a un interprete. Ho un sistema di tag XML che sto usando per marcare sezioni del file in un modo che, si spera, non sia in conflitto con nessuna delle altre lingue. I marcatori appaiono così:

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

I s # 'sono gli indicatori di commento, ma gli indicatori di commento possono essere cose diverse a seconda della lingua della sezione.

Il problema che ho è che non riesco a trovare un modo per isolare solo quella sezione del file. Posso caricare l'intero file in memoria, ma non riesco a ottenere il materiale tra i tag. Qui è il mio codice corrente:

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

Tutto quello che ho provato risultati finora in tutto il file viene emesso nel Contents piuttosto che solo il codice tra i marcatori. Ho provato diversi metodi per sfuggire ai simboli usati nei marcatori, ma ha sempre come risultato la stessa cosa.

NOTA: L'uso del ^ è necessario perché l'interprete di primo livello è Batch, che riaggancia sulle staffe angolari e altre cose a caso.

+0

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

+0

In realtà restituisce l'intero contenuto del file tranne gli indicatori stessi. Vale a dire. lang_a # ... lingua b ... # lang_c – BHarms

+0

C'è diversi o solo un isolato? Se è solo uno, puoi usare la stessa regex, ma con l'operatore '-match', e quindi accedere al testo usando la variabile' $ matches [1] 'che è impostata come risultato di' -match'. –

risposta

5

Poiché v'è un solo isolato, è possibile utilizzare l'espressione regolare

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

ma con -match operatore, e quindi accedere al testo utilizzando $matches[1] variabile che è impostato a seguito di -match.

Così, dopo la dichiarazione regex, utilizzare

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

Sì. Inoltre, ho aggiunto un ^^. * Lì per assicurarmi che l'inizio dell'ultima riga non fosse incluso: '$ re = '(? S)^<{LANGB}^> (. *) ^^. *^<{/LANGB}^>' ;^' – BHarms

+0

Vedo, ho aggiunto quella modifica. –