【问题标题】:Passing string included dollar signs to -Replace Variable将包含美元符号的字符串传递给 -Replace 变量
【发布时间】:2015-12-28 15:46:41
【问题描述】:

我正在尝试使用 powershell 替换 .config 文件中的一个句子。

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

'$BASE_PATH$\Test\bin`$Test_TYPE`$\WebTest.dll' , 'c:\program Files\example\webtest.dll'

每次我尝试运行上面的代码时都会得到

"无效的正则表达式模式: $BASE_PATH$\Test\bin\$Test_TYPE$\WebTest.dll" 在 c:\tests\runtesting.ps1 -replace

如果我不使用反引号,美元符号会消失,一些文字会消失。

如何将字符串中的美元符号传递给 -replace?

【问题讨论】:

  • 在我的答案中添加了代码。

标签: powershell


【解决方案1】:

这是关于如何转义正则表达式。每个特殊字符(对于正则表达式来说是特殊的),例如 $ 都应该用 \ 转义

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

当正则表达式如下时,将使用反引号:

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

【讨论】:

  • 当我尝试您的示例时,它运行良好,但是当我在我的代码上尝试如下时,没有运气。 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'
  • 在提交我的评论之前,第二个选项在反引号之后有反斜杠......但现在它们没有显示。
  • 尝试了以下操作并在美元符号前添加一个(斜杠+反引号)并在现有反斜杠前添加另一个反斜杠后工作,用双引号打开和关闭字符串... -replace "`$ BASE_PATH`$\\Test\\bin\\`$Test_TYPE`$\\WebTest.dll"
  • '"`$BASE_PATH`$\\Test\\bin\\`$Test_TYPE`$\\WebTest.dll"'
  • 我编辑了代码,以便正确替换字符串 '$BASE_PATH$\Test\bin$Test_TYPE$\WebTest.dll'
【解决方案2】:

通过:

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

改为:

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

逻辑:

  • 在每个美元符号前输入\`
  • 在每个反斜杠之前输入另一个反斜杠 \
  • 用双引号“”关闭字符串

【讨论】:

  • 这让我投了赞成票,因为它对问题提供了最简单、最简洁的解释。
  • 赞成解释转义 $ 字符的逻辑
【解决方案3】:

只是为stej's answer 提供更多背景知识,这里有两件事:

1) 解析命令时,powershell 在-replace 的字符串参数中为expanding the variables(例如,字符串"shell: $ShellId" 将扩展ShellId 变量,产生@987654328 @)。使用反引号转义字符,或用单引号声明字符串,可以防止这种情况发生("shell: `$ShellId"'shell: $ShellId' 都变为 shell: $ShellId)。

2) -replace 运算符使用.NET regular expressions,其中$\. 字符是特殊的语言元素。使用反斜杠转义字符允许将特殊字符视为正则表达式中的文字值(例如,\$ 将匹配美元字符,而$ 将匹配行尾)。由于$ 被powershell 和正则表达式使用,它必须被转义两次(使用"\`$"'\$')。

在这种情况下,另一种选择是使用string.Replace 方法,该方法将执行区分大小写的替换:

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

【讨论】:

    【解决方案4】:

    对于那些不熟悉区别的人,重要的是不要将反引号字符(`)单引号字符混淆(') 在这些转义中。例如:

    [SUCCESS] 双引号作为容器,反斜杠-反引号作为转义:

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

    [FAIL] 双引号作为容器,反斜杠撇号作为转义:

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

    [SUCCESS] 单引号作为容器,用简单的反斜杠作为转义:

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

    [FAIL] 单引号作为容器,反斜杠-反引号作为转义:

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

    总的来说,最简单的选择可能是使用单引号作为容器,使用单反斜杠作为转义:'\$old'

    【讨论】:

      猜你喜欢
      • 2021-10-04
      • 2012-09-11
      • 1970-01-01
      • 1970-01-01
      • 2011-04-03
      • 2020-10-12
      • 2019-12-04
      • 2018-04-01
      • 2020-09-29
      相关资源
      最近更新 更多