kamcknig
kamcknig

Reputation: 935

Powershell expansion of regular expression groups and other variables

I'm trying to use regular expressions to match and replace text in a file. I'm using capture groups also. In the replacement text I'm using the capture groups and other variables that I want expanded. The problem is that when the other variables' values start with a number they get expanded and I assume are trying to then expand as a captured group that doesn't exist.

Here is the text before the replace

merchantId="101"

And here is the text after the replace using 101 as the input for the Read-Host command.

$1101"

And using this to match and replace the text

$merchant = Read-Host 'What merchant would you like to use?'
$configPath = '..\src\config.cfg'

(Get-Content $configPath) | ForEach-Object {
    $_ -replace "(merchantId="").*("")\s*$", "`$1$merchant`$2"
}

Merchant is always a number, so when the user enters something like 101 for merchant then the replacement text looks like it's expanded to $1101 and so I assume powershell is then looking for the 1101th captured group which of course doesn't exist.

I'm new to powerhsell and the syntax is a little weird for me, not sure how to go about this.

Upvotes: 0

Views: 458

Answers (1)

Matt
Matt

Reputation: 46710

You are correct in your assumption. Not sure if PowerShell or the regex engine is at fault but it is trying to find a capture group that does not exist. When that happens the string literal is returned. If your $merchant was alphabetical you would not have this issue.

A simple solution is the one that PetSerAl provides. It gives a distinction between the variable and capture group.

$_ -replace "(merchantId="").*("")\s*$", "`${1}$merchant`$2"

However you really don't need to be doing it the way you are. Since you are just replacing the value entirely and care not for the previous value why not just overwrite outright?

(Get-Content $configPath) | ForEach-Object {
    If($_ -match "^merchantId="){
        'merchantId="{0}"' -f $merchant
    } else {
        $_
    }
}

Not the prettiest code but it works.

Upvotes: 1

Related Questions