2015-07-13 236 views
1

我正在尝试开发一个脚本,用新的测试字符串替换输入文本中的某些标记。随着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

回答

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 
} 

的作品,因为在正则表达式,你必须逃离$用正则表达式转义字符\

1

-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) 
1

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

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

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