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
-replace
operator, 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$1
in 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
$1
may 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 :