【问题标题】:Replacing Strings Containing $ Characters替换包含 $ 字符的字符串
【发布时间】:2015-07-13 08:48:28
【问题描述】:

我正在尝试开发一个脚本,将输入文本中的某些标记替换为新的测试字符串。在this 的帮助下,我开发了以下内容:

$repl = @{}
$repl.add('SVN',"myworkspace\BRANCH71")
$repl.add('REL',"72")

$string = 'C:\users\rojomoke\filesREL\SVN\blah.txt'
foreach ($h in $repl.getenumerator())
{
    write-host "Line: $($h.name): $($h.value)"
    $string = $string -replace "$($h.name)","$($h.value)"
    write-host $string
}

产生所需的C:\users\rojomoke\files72\myworkspace\BRANCH71\blah.txt

但是,当我尝试使用以$ 符号开头的标记时,这一切都归于 sh^H^Hpieces。如果在上面的示例中我使用标记 $REL$SVN,则不会发生替换,$string 仍为 C:\users\rojomoke\files$REL\$SVN\blah.txt

我假设我正在与正则表达式扩展或其他东西发生冲突,但我不知道如何。是否可以引用美元符号以使其正常工作?

我使用的是 Powershell 版本 3。

【问题讨论】:

    标签: powershell replace associative-array powershell-3.0


    【解决方案1】:
    $repl = @{}
    $repl.add('\$SVN',"myworkspace\BRANCH71")
    $repl.add('\$REL',"72")
    
    $string = 'C:\users\rojomoke\files$REL\$SVN\blah.txt'
    foreach ($h in $repl.getenumerator()) {
        write-host "Line: $($h.name): $($h.value)"
        $string = $string -replace "$($h.name)","$($h.value)"
        write-host $string
    }
    

    之所以有效,是因为在正则表达式中,您必须使用正则表达式转义字符 \ 转义 $

    【讨论】:

      【解决方案2】:

      -replace 运算符使用正则表达式匹配。 $character 在正则表达式(“字符串结尾”)中具有特殊含义,其他一些字符也是如此。为避免这种情况,您必须在搜索字符串中转义这些字符:

      $srch = [regex]::Escape('$SVN')
      $repl = 'myworkspace\BRANCH71'
      
      $string = 'C:\users\rojomoke\filesREL\$SVN\blah.txt'
      
      $string -replace $srch, $repl
      

      但是,如果你仍然使用类似变量的语法,为什么不直接使用变量呢?

      $repl = @{
        'SVN' = 'myworkspace\BRANCH71'
        'REL' = '72'
      }
      
      $repl.GetEnumerator() | % { New-Variable -Name $_.Name -Value $_.Value }
      
      $string = "C:\users\rojomoke\files$REL\$SVN\blah.txt"
      

      如果需要在定义嵌套变量之前定义$string,可以用单引号定义字符串并在稍后的时间点求值:

      $repl = @{
        'SVN' = 'myworkspace\BRANCH71'
        'REL' = '72'
      }
      
      $repl.GetEnumerator() | % { New-Variable -Name $_.Name -Value $_.Value }
      
      $string = 'C:\users\rojomoke\files$REL\$SVN\blah.txt'
      
      $expandedString = $ExecutionContext.InvokeCommand.ExpandString($string)
      

      【讨论】:

        【解决方案3】:

        -replace 将第一个参数视为正则表达式模式。在正则表达式中,$ 是一个特殊字符,表示字符串的最后一个字符位置(“end”)。因此,当试图匹配字符串中的文字字符$ 时,您需要对其进行转义。

        您可以为此使用[regex]::Escape($pattern)

        $repl = @{}
        $repl.add([regex]::Escape('$SVN'),"myworkspace\BRANCH71")
        $repl.add([regex]::Escape('$REL'),"72")
        

        【讨论】:

          猜你喜欢
          • 2021-06-08
          • 1970-01-01
          • 2011-03-10
          • 2014-03-30
          • 2019-05-25
          • 2021-08-19
          • 2019-12-04
          • 2018-12-13
          • 2019-09-10
          相关资源
          最近更新 更多