替换包含$字符的字符串
问题描述:
我正在尝试开发一个脚本,用新的测试字符串替换输入文本中的某些标记。随着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
答
$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
}
的作品,因为在正则表达式,你必须逃离$
用正则表达式转义字符\
。
答
的-replace
操作员使用正则表达式匹配。 $
字符在正则表达式(“字符串的结尾”)中具有特殊含义,就像其他字符一样。为了避免这种情况,你必须逃脱的搜索字符串这些字符:
$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)
答
-replace
治疗的第一个参数作为正则表达式模式。在正则表达式中,$
是一个特殊字符,表示字符串的最后一个字符位置(“结束”)。因此,当试图在字符串中匹配文字字符$
时,您需要将其转义。
您可以使用[regex]::Escape($pattern)
此:
$repl = @{}
$repl.add([regex]::Escape('$SVN'),"myworkspace\BRANCH71")
$repl.add([regex]::Escape('$REL'),"72")