开发者

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'

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜