Passing string included dollar signs to -Replace Variable
I am trying to replace a sentence in .config file using powershell.
${c:Web.config} = ${c:Web.config} -replace
'$BASE_PATH
$\Test\bin`$Test_TYPE`$\WebTest.dll' , 'c:\program Files\example\webtest.dll'
Everytime I try to run the above code I get
"Invalid regular expression pattern: $BASE_PATH$\Test\bin\$Test_TYPE$\WebTest.dll" at c:\tests\runtesting.ps1 -replace <<<< $BASE_PATH$\Test\bin\$Test_TYPE$\WebTest.dll
If I don't use the backtick the dollar signs will disappear and some text.
How would I pass dollar signs in a string to -replace开发者_开发百科?
This is about how to escape regexes. Every special character (special with regards to regular expressions) such as $
should be escaped with \
'$A$B()[].?etc' -replace '\$|\(|\)|\[|\]|\.|\?','x'
'$BASE_PATH$\Test\bin$Test_TYPE$\WebTest.dll' -replace '\$BASE_PATH\$\\Test\\bin\$Test_TYPE\$\\WebTest.dll','something'
The backtick would be used when the regex would be like this:
'$A$B' -replace "\`$",'x'
To Pass:
$BASE_PATH$\Test\bin\$Test_TYPE$\WebTest.dll
Change to:
`"\`$BASE_PATH\`$\\Test\\bin\\\`$Test_TYPE\`$\\WebTest.dll"`
Logic:
- Before every dollar sign enter \`
- Before every backslash enter another back slash \
- Close string with double quotes ""
Just to provide a bit more background to stej's answer, there are two things going on here:
1) While parsing the command, powershell is expanding the variables in the string arguments to -replace
(for example, the string "shell: $ShellId"
will expand the ShellId
variable, producing shell: Microsoft.PowerShell
). Using the backtick escape character, or declaring the string with single quotes, prevents this (both "shell: `$ShellId"
and 'shell: $ShellId'
become shell: $ShellId
).
2) The -replace
operator uses .NET regular expressions, where the $
, \
, and .
characters are special language elements. Using the backslash escape character allows special characters to be treated as literal values within the regular expression (e.g. \$
will match a dollar character, while $
will match the end of the line). Since $
is used by both powershell and regular expressions, it has to be escaped twice (using either "\`$"
or '\$'
).
In this case, another alternative would be to use the string.Replace
method, which will perform a case-sensitive replacement:
${c:Web.config}.Replace(
'$BASE_PATH$\Test\bin$Test_TYPE$\WebTest.dll',
'c:\program Files\example\webtest.dll'
)
For those unfamiliar with the distinction, it is important not to confuse the backtick character (`) with the single-quotation character (') in these escapes. For example:
[SUCCESS] Double quotes as container with backslash-backtick as escape:
PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace "\`$old", "(New)"}
What is (New)?
PS C:\Temp>
[FAIL] Double quotes as container with backslash-apostrophe as escape:
PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace "\'$old", "(New)"}
What is $old?
PS C:\Temp>
[SUCCESS] Single quotes as container with simple backslash as escape:
PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace '\$old', "(New)"}
What is (New)?
PS C:\Temp>
[FAIL] Single quotes as container with backslash-backtick as escape:
PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace '\`$old', "(New)"}
What is $old?
PS C:\Temp>
Overall, the easiest option may be to use single quotes as the container and a single backslash as the escape: '\$old'
精彩评论