2010-02-05 11 views
6

Sto provando a sostituire una frase nel file .config usando powershell.Passing string included dollar signs to -Replace Variable

${c:Web.config} = ${c:Web.config} -replace 

'$BASE_PATH $ \ Test \ bin` $ Test_TYPE` $ \ WebTest.dll', 'C: \ Program Files \ esempio \ webtest.dll'

Ogni volta che tenta di eseguire il codice di cui sopra ottengo

"non valido modello di espressione regolare: $ BASE_PATH $ \ test \ bin \ $ Test_TYPE $ \ WebTest.dll" in c: \ test \ runtesting.ps1 -replace < < < < $ BASE_PATH $ \ Test \ bin \ $ Test_TYPE $ \ WebTest.dll

Se io non uso il backtick Giusto spariranno e del testo.

Come passarei i segni del dollaro in una stringa per -replace?

+0

Codice aggiunto alla mia risposta. – stej

risposta

5

Questo è su come evitare le espressioni regolari. Ogni carattere speciale (speciale per quanto riguarda le espressioni regolari) come $ dovrebbero essere preceduti da \

'$A$B()[].?etc' -replace '\$|\(|\)|\[|\]|\.|\?','x' 
'$BASE_PATH$\Test\bin$Test_TYPE$\WebTest.dll' -replace '\$BASE_PATH\$\\Test\\bin\$Test_TYPE\$\\WebTest.dll','something' 

L'apice inverso sarebbe stato utilizzato quando la regex sarebbe come questo:

'$A$B' -replace "\`$",'x' 
+0

Quando ho provato il tuo esempio ha funzionato perfettamente, ma quando ho provato il mio codice come segue, non ha avuto fortuna. 1) '\ $ BASE_PATH \ $ \ Test \ bin \\ $ Test_TYPE \ $ \ WebTest.dll', 'c: \ program Files \ example \ webtest.dll' 2) "\' $ BASE_PATH \ ' $ \ Test \ bin \\ '$ Test_TYPE \' $ \ WebTest.dll ", 'c: \ program Files \ example \ webtest.dll' –

+0

Prima di inoltrare il mio commento la seconda opzione aveva i backslash subito dopo il backtick ... ma ora non stanno mostrando. –

+0

Provato quanto segue e lavorato dopo aver aggiunto una barra (+ backtick) prima di un segno di dollaro e un'altra barra rovesciata prima di una barra rovesciata esistente, aperta e chiusa la stringa con virgolette doppie ... -replace "\' $ BASE_PATH \ '$ \ \ Test \\ bin \\\ '$ Test_TYPE \' $ \\ WebTest.dll " –

3

a passare:

$BASE_PATH$\Test\bin\$Test_TYPE$\WebTest.dll 

Passa a:

`"\`$BASE_PATH\`$\\Test\\bin\\\`$Test_TYPE\`$\\WebTest.dll"` 

Logic:

  • Prima di ogni segno del dollaro entrare \ `
  • Prima di ogni barra rovesciata entrare in un'altra barra rovesciata \
  • Chiudi stringa con virgolette doppie ""
+0

Questo è il mio voto positivo perché ha offerto la spiegazione più semplice e concisa del problema. –

1

solo per fornire un un po 'più di fondo a stej's answer, ci sono due cose che succedono qui:

1) Durante l'analisi del comando, powershell è expanding the variables negli argomenti stringa su -replace (ad esempio, la stringa "shell: $ShellId" espande la variabile ShellId, producendo shell: Microsoft.PowerShell). L'utilizzo del carattere di escape backtick o la dichiarazione della stringa con virgolette singole impedisce questo (sia "shell: `$ShellId" che shell: $ShellId diventano shell: $ShellId).

2) L'operatore -replace utilizza .NET regular expressions, dove i $, \ e . personaggi sono elementi del linguaggio speciali.L'utilizzo del carattere di escape barra rovesciata consente ai caratteri speciali di essere trattati come valori letterali all'interno dell'espressione regolare (ad esempio \$ corrisponderà a un carattere dollaro, mentre $ corrisponderà alla fine della riga). Dal momento che il $ viene utilizzato sia da PowerShell sia da espressioni regolari, deve essere sfuggito due volte (utilizzando "\`$" o '\$').

In questo caso, un'altra alternativa potrebbe essere quella di utilizzare il metodo string.Replace, che esegue una sostituzione-sensitive:

${c:Web.config}.Replace(
    '$BASE_PATH$\Test\bin$Test_TYPE$\WebTest.dll', 
    'c:\program Files\example\webtest.dll' 
) 
1

Per chi non conosce la distinzione, è importante non confondere il backtick carattere (`) con la virgolette carattere (') in queste fughe. Per esempio:

[SUCCESSO] doppi apici come contenitore con Barra-apice inverso come escape:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace "\`$old", "(New)"} 
What is (New)? 
PS C:\Temp> 

[FAIL] doppi apici come contenitore con Barra-apostrofo come via di fuga:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace "\'$old", "(New)"} 
What is $old? 
PS C:\Temp> 

[SUCCESS] virgolette singole come contenitore con barra rovesciata semplice come fuga:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace '\$old', "(New)"} 
What is (New)? 
PS C:\Temp> 

[FAIL] virgolette singole come contenitore con Barra-apice inverso come escape:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace '\`$old', "(New)"} 
What is $old? 
PS C:\Temp> 

Nel complesso, l'opzione più semplice potrebbe essere quella di utilizzare le virgolette singole, come il contenitore e una singola barra rovesciata come la fuga : '\$old'