Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replace with evaluated code in powershell?

I'm having some difficulty finding a "native" powershell -replace call that would replace a match with something based on the match. E.g. in perl it would be like this:

my %definedVars = ( ab => "hello", cd => "there" );
my $str = q"$(ab) $(cd)";
$str =~ s/\$\(([^)]+)\)/$definedVars{$1}/ge;
print "$str\n";

I was thinking that in powershell, it'd be something like this:

$definedVars = @{ ab = 'hello'; cd = 'there' }
'$(ab) $(cd)' -replace "\$\(([^)]+)\)", { $definedVars[$1] }

I've looked around and I think that the -replace switch doesn't have an deferred evaluator, so I'd have to use the .NET replace function, but I'm not entirely sure how that works. I'm thinking it would be something like this:

$definedVars = @{ ab = 'hello'; cd = 'there' }
[regex]::replace('$(ab) $(cd)',
   "\$\(([^)]+)\)",
   { $definedVars[$_.Groups[1].Value] } )

Documentation is sparse, so if you could also state where you got your info from, that would be great.

like image 636
Adrian Avatar asked Jun 06 '26 01:06

Adrian


1 Answers

Looks like it is just a syntax problem. I have to specify the parameter and use that. $_ is not defined as a special default parameter. So it would be like this:

$definedVars = @{ ab = 'hello'; cd = 'there' }
[regex]::replace('$(ab) $(cd)',
   "\$\(([^)]+)\)",
   { param($m); $definedVars[$m.Groups[1].Value] } )

Edit

As mjolinor pointed out, instead of defining the params, I could use $args array instead, like this:

$definedVars = @{ ab = 'hello'; cd = 'there' }
[regex]::replace('$(ab) $(cd)',
   "\$\(([^)]+)\)",
   { $definedVars[$args[0].Groups[1].Value] } )

This is slightly better if I'm only referencing that parameter once, but if the delegate gets more complex, IMO it would still be better to use param to specify the parameters.

like image 189
Adrian Avatar answered Jun 07 '26 18:06

Adrian