0

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.

kamcknig
  • 883
  • 3
  • 9
  • 27
  • 3
    I think it might be easier to understand this if you gave some before and after examples of the text you're trying to modify. Can you edit the question to include those? – arco444 Sep 09 '15 at 14:20
  • It would be helpful if you could list what you want the end result of the replacement to look like; it is also helpful to have some sample text so we can double-check the regular expression syntax. But as a general tip, because powershell's variable character is '$', I tend to used named capture groups. That might get around the issue you're seeing here. – jbsmith Sep 09 '15 at 14:42
  • 2
    ``"`${1}$merchant`$2"`` – user4003407 Sep 09 '15 at 14:44

1 Answers1

1

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.

Community
  • 1
  • 1
Matt
  • 45,022
  • 8
  • 78
  • 119