2015-07-13 3 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.

Однако, я стараюсь использовать маркеры, отмеченные знаком, начиная с знака $. Если в приведенном выше примере я использую токены $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") 
Смежные вопросы