PowerShell Regex Example - Incrementing Matches

In the PowerShell Slack, I recently answered a question along these lines. Say you have a string that reads “first thing {} second thing {}” and you want to get to “first thing {0} second thing {1}” so that you can use the -f  operator to insert values into those spots. For instance…

"first thing {0} second thing {1}" -f $(get-date -format yyyy-MM-dd), $(get-random)
# Will return "first thing 2018-01-10 second thing <a random number>"

The question is: how can you replace the {}’s in the string to {<current number>}?

You might think you could do something like this.

$string = 'first thing {} second thing {}'
$i = 0
[regex]::replace($string, "\{\}", {"{$($i)}"; $i++})

But you’d be disappointed.

If you’re not sure what’s going on, the [regex] accelerator has a replace  method that works like -replace  does. It takes three arguments: the string that is being worked on, the pattern being detected, and what to replace the pattern with. In this case, I gave it a scriptblock to replace it with the value of $i  and then increment the value of the variable by one. Unfortunately, it doesn’t look like $i  gets incremented. Everything gets replaced with a {0}  instead of an incremented number.

Long story short, this is a PowerShell scoping issue. If you make $i  a part of a bigger scope like global, script, or something that makes sense for your situation, you’ll get the results you desire (global is probably not the best choice).

$string = 'first thing {} second thing {}'
$global:i = 0
[regex]::replace($string, "\{\}", {"{$($global:i)}"; $global:i++})

#returns first thing {0} second thing {1}

And this will work just fine in your -f  replacement operations!

Written on January 10, 2018