Reputation: 8900
Say I have an XML-based template string in which I have to replace self-made template markers:
$template = '<Foo Name="${BAZ}">'
I would like to replace the literal ${BAZ}
with a value. I thought using the case-sensitive -creplace
operator would be a good idea. As givens, I have both the bare parameter name (BAZ
) without the additional adornment (${
}
) and its value (42):
$param = 'BAZ'
$value = 42
So I first derive my replacement string using -f
to mix the parameter name with its "markup", while carefully escaping the literal {
and }
within the format string:
$needle = '${{{0}}}' -f $param
# ${BAZ}
# at least when printed...
Now to the final act:
$template -creplace $needle, $value
# <Foo Name="${BAZ}">
# so $needle does not seem to match the string '${BAZ}'
I seem to have missed (or overcompensated) for some escaping somewhere in between... can somebody pull me off the ice here? (I have tried many combinations of backspaces, backticks, single- and double-quoted strings. And just for context: in my real script, $template
is a large multi-line string via $template = Get-Content "template-file.xml"
, which I hope is not the root source.)
Edit: I have found a working solution after some more hunting: by ditching -creplace
in favour of .net's Replace()
method, the above $needle
matches the template:
$template.Replace($needle, $value)
# <Foo Name="42"/>
So I would be glad about any answer that sheds some light on why -creplace
does not cooperate, what I could do to make it.
Upvotes: 1
Views: 840
Reputation: 3596
-replace
is an operator that replaces a regular expression.-creplace
just makes this regular expression case sensitive. The problem you are running into is the regular expression itself, as certain characters have a special role in regex.
What you want to do, is to escape such characters:
$template -replace [regex]::escape($needle), $value
The escaped pattern will look like this: \$\{BAZ}
Upvotes: 1
Reputation: 3918
In this case [regex]::escape()
should do the trick.
$template = '<Foo Name="${BAZ}">'
$template -match [regex]::escape('${BAZ}')
$Matches
Output:
Name Value
---- -----
0 ${BAZ}
Upvotes: 2