Skip to content

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

Description

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

Activity

  1. lzybkr commented on Feb 16, 2018

    @lzybkr
    Contributor

    This is approved in in review, see #6029

  2. LaurentDardenne commented on Feb 16, 2018

    @LaurentDardenne

    To allow this call would also be appreciated :

    'Increment these numbers: 1 2 3' -replace '\d +', {[int] $ Args.Value + 1}, $Count, $StartAt
  3. iSazonov commented on Feb 20, 2018

    @iSazonov
    Collaborator

    Laurent Dardenne (@LaurentDardenne) Please open new issue for your suggestion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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