1

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?

adekcz
  • 340
  • 2
  • 13

3 Answers3

2

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.
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
0

tl;dr

# * 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}$$'

Background information and guidance:

  • 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 $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: $'))
  • 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.

For a comprehensive overview of PowerShell's -replace operator, see this answer.

mklement0
  • 382,024
  • 64
  • 607
  • 775
0

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 :
js2010
  • 23,033
  • 6
  • 64
  • 66