Skip to content

Enhancement: support a script block as the replacement operand of the -replace operator to enable dynamic substitutions  #6164

@mklement0

Description

@mklement0

Wishful thinking:

# Script block as replacement operand allows dynamic substitutions.
# TBD: how to refer to the match at hand in the script block.
> 'Increment these numbers: 1 2 3' -replace '\d+', { [int] $Args.Value + 1 }   
Increment these numbers: 2 3 4

Sometimes string replacements need to be dynamic, i.e., the replacement string must be derived from the match at hand.

Consider the following (contrived example):

You want to increment all numbers in an input string; e.g.:

'Increment these numbers: 1 2 3' -> 'Increment these numbers: 2 3 4'

Currently, -replace doesn't support this type of replacement, because the replacement operand can only statically refer to the match at hand ($& for the match in full, $1 for the 1st capture group's match (if any), ...).

Thus, to achieve this kind of substitution the .NET Framework must currently be used:

> [regex]::Replace('Increment these numbers: 1 2 3', '\d+', { param($match) [int] $match.Value + 1 })
Increment these numbers: 2 3 4

Needless to say, this is neither PowerShell-like nor simple.


Supporting the syntax as proposed at the top would greatly simplify such operations.

Syntax details

The simplest approach is to use [regex]::Replace() as-is behind the scenes, and let the script block reference the match at hand - which is passed as a [System.Text.RegularExpressions.Match] instance - via $Args (or, optionally, an explicitly defined parameter via param()).

The alternative is to stick with the $&, $1, ... syntax, but that would require behind-the-scenes manipulation of the script block.

Backward-compatibility considerations

Currently, attempting to use a script block as the replacement operand simply stringifies that block (i.e., uses its string contents as the replacement string).

Since this behavior isn't useful, it's hard to imagine anyone relying on it, so this change probably falls into Bucket 3: Unlikely Grey Area

Environment data

Written as of PowerShell Core v6.0.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Enhancementthe issue is more of a feature request than a bugResolution-FixedThe issue is fixed.WG-Languageparser, language semantics

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions