Как избежать долларовых и фигурных скобок для замены операторов в Powershell - PullRequest
0 голосов
/ 11 декабря 2018

Скажем, у меня есть строка шаблона на основе XML, в которой я должен заменить самодельные маркеры шаблона:

 $template = '<Foo Name="${BAZ}">'

Я хотел бы заменить литерал ${BAZ} значением.Я думал, что использование чувствительного к регистру оператора -creplace было бы хорошей идеей.Как и у меня, у меня есть как пустое имя параметра (BAZ) без дополнительного украшения (${ }), так и его значение (42):

 $param = 'BAZ'
 $value = 42

Поэтому я сначала получаю строку заменыиспользуя -f для смешивания имени параметра с его «разметкой», при этом тщательно экранируя литерал { и } в строке формата:

 $needle = '${{{0}}}' -f $param 
 # ${BAZ}
 # at least when printed...

Теперь к финальному действию:

 $template -creplace $needle, $value
 # <Foo Name="${BAZ}">
 # so $needle does not seem to match the string '${BAZ}'

Кажется, я упустил (или перекомпенсировал) что-то сбежавшее где-то посередине ... Может ли кто-нибудь вытащить меня сюда со льда?(Я пробовал много комбинаций обратных символов, обратных кавычек, одинарных и двойных кавычек. И просто для контекста: в моем реальном сценарии $template - это большая многострочная строка через $template = Get-Content "template-file.xml",который, я надеюсь, не является корневым источником.)


Редактировать: Я нашел рабочее решение после некоторой дополнительной охоты: отказавшись от -creplace в пользу .net's Replace() метод, приведенный выше $needle соответствует шаблону:

 $template.Replace($needle, $value)
 # <Foo Name="42"/>

Так что я был бы рад любому ответу, который пролил бы свет на то, почему -creplace не сотрудничает, что я мог бы сделать, чтобы сделать это.

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

-replace - это оператор, который заменяет регулярное выражение. -creplace просто делает это регулярное выражение чувствительным к регистру.Проблема, с которой вы сталкиваетесь, заключается в самом регулярном выражении, поскольку определенные символы играют особую роль в регулярном выражении.

Что вы хотите сделать, это экранировать такие символы:

 $template -replace [regex]::escape($needle), $value

экранированный шаблон будет выглядеть так: \$\{BAZ}

0 голосов
/ 11 декабря 2018

В этом случае [regex]::escape() должен сделать трюк.

 $template = '<Foo Name="${BAZ}">'
 $template -match [regex]::escape('${BAZ}')
 $Matches

Вывод:

Name                           Value 
----                           ----- 
0                              ${BAZ}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...