I want to replace strings like url: `= this.url` with url: $url$
I got quite close with this:
(Get-Content '.\file') -Replace "``= this.(\w )``", "$ `$1$"
with output url: $ url$.
But when I remove extra space then the output breaks.
How can I escape/modify "$`$1$" so that it works?
CodePudding user response:
You can use
-Replace "``= this\.(\w )``", '$$$1$$'
Note that
- The
.must be escaped in the regex pattern '$$$1$$'is a$$$1$$string that contains:$$- a literal single$char$1- the backreference to the first capturing group$$- a literal single$char.
CodePudding user response:
To complement Wiktor's effective answer with background information and guidance:
# * Consistent use of '...', obviating the need to `-escape ` and $
# * Verbatim $ chars. in the substitution string escaped as $$
# * Capture-group reference $1 represented as ${1} for visual clarity.
(Get-Content .\file) -replace '`= this\.(\w )`', '$$${1}$$'
In the substitution operand of PowerShell's regex-based
-replaceoperator, a verbatim$character must be escaped as$$, given that$-prefixed tokens have special meaning, namely to refer to results of the regex matching operation, such as$1in your command (a reference to what the 1st, unnamed capture group in the search regex captured).Unlike what the docs partially suggest, such a substitution string is not itself a regex, and any other characters are used verbatim.
To programmatically escape
$for verbatim use in a substitution string, it's simplest to use the.Replace().NET string method, which performs _verbatim (literal) replacements (assuming that all$instance are to be escaped; e.g.'$foo$'.Replace('$', '$$')Note that, situationally, a capture-group reference such as
$1may need to be disambiguated as${1}, and you may always choose to do that for visual clarity, as shown above.
It is only the search operand is a regex, and there all characters that are regex metacharacters must be
\-escaped in order to be used verbatim, which can be done:- character-individually, in string literals (
amount: \$) - programmatically, for entire strings, using
[regex]::Escape()([regex]::Escape('amount: $'))
- character-individually, in string literals (
To avoid confusion over up-front string interpolation by PowerShell vs. what the .NET regex engine ends up seeing, it's best to consistently use verbatim (single-quoted) strings (
'...') rather than expandable (double-quoted) strings ("...").- If embedding PowerShell variable values is needed, use techniques such as:
string concatenation (
'^' [regex]::Escape($foo) '$')or
-f, the format operator ('^{0}$' -f [regex]::Escape($foo))In your case, using
'...'helps you avoid the`-escaping that"..."requires to make PowerShell treat$and`(and") verbatim, as shown above.
- If embedding PowerShell variable values is needed, use techniques such as:
For a comprehensive overview of PowerShell's -replace operator, see this answer.
CodePudding user response:
Powershell 7 version of -replace with a scriptblock 2nd argument. Just assigning $_ into $a to look at it. Note the backquote is a special character inside doublequotes, which I'm avoiding.
'url: `= this.url`' -replace '`= this\.(\w )`', {$a = $_; '$' $_.groups[1] '$'}
url: $url$
$a
Groups : {0, 1}
Success : True
Name : 0
Captures : {0}
Index : 5
Length : 12
Value : `= this.url`
ValueSpan :
