In order to treat a search expression passed to the regex-based -replace
operator as a literal string, you must escape regex metacharacters such as ?
, which you can do programmatically by calling [regex]::Escape()
(in a literal regex string, you could manually escape indiv. chars. with \
):
(Get-Content exp.txt) -replace [regex]::Escape($ar[$i]), '$&~'
Note how I've used '...'
(single-quoting) for the replacement operand, which is preferable so as to avoid confusion with the string expansion that PowerShell itself performs up front in "..."
(double-quoted) strings. Similarly, '...'
is preferable for a literal search regex.
Sticking with the regex-based -replace
operator in your case makes sense for two reasons:
You want to (directly and succinctly) refer to whatever was matched by the regex in the replacement expression, via placeholder $&
.
You want to perform replacements on an array of input strings in a single operation (like many PowerShell operators, -replace
supports an array of strings as its LHS, and then operates on each element).
By contrast, in cases where literal string substitutions with a single input string is needed, use of the [string]
type's .Replace()
method is the simpler and faster option, but note that it is case-sensitive by default (unlike -replace
).
See this answer for details.