Powershell: Force immediate evaluation of backrefe

2019-02-27 10:55发布

问题:

I am running into an error where I am concatenating strings together to obtain the field I want replaced.

Below is an example of what my script is doing:

$TEXTTOREPLACEWITH= '6Q'

(Get-Content testfile.html) | ForEach-Object { $_ -replace '(.*)\$\(STRINGTOREPLACE\)(.*)', ('$1' +$TEXTTOREPLACEWITH+'$2')

If I ran this against a file that had a line input as follows:

abc$(STRINGTOREPLACE)xyz

I expect the following output:

abc6Qxyz

INSTEAD, When I run this script the output looks as follows:

$16Qxyz

I'm assuming this is due to the fact that back-references must not be resolved until string concatenation is complete. Is there any way in PowerShell to go ahead and resolve these back-references immediately and avoid the output that I am seeing?

Thanks,

Josh

回答1:

1st, missing the point, answer replaced...

When concatenate '$1' and '6Q' (before being passed to the regex engine) you get $16Q and there is no 16th capture to replace.

To avoid this, use named groups in the match ((?<name>)) and ${name} in the replacement string.

See the documentation, and note:

If number does not specify a valid capturing group defined in the regular expression pattern, $number is interpreted as a literal character sequence that is used to replace each match.



回答2:

You can also try using named capture groups:

$rx = '(?i)(?<Beg>.*)\$\(STRINGTOREPLACE\)(?<End>.*)'
$texttoreplacewith='${Beg}6Q${End}'
$x = "abc`$(stringtoreplace)xyz"

[regex]::Replace($x, $rx, $texttoreplacewith)