This question表示在引用其他变量时,可以使用反勾来解决双引号字符串中的捕获组。
(如果需要)在替换表达式中引用其他变量,可以使用双引号字符串,并使用反引号将捕获的美元转义
但是,我看到了一些我无法解释的有趣行为。
$VersionReplacementRegex = "(\d+\.)\d+\.\d+\.\d+"
$BuildVersionValidationRegex = "\d+\.\d+\.\d+-\w\d+"
$VersionData = [regex]::matches("some-18.11.8",$BuildVersionValidationRegex)
$NewVersion = $VersionData[0]
$filecontent = "stuff 1.0.0.0 other stuff" #Get-Content($file)
使用链接问题中指定的捕获组替换$filecontent
中的文本会导致结果不完整...
$filecontent -replace $VersionReplacementRegex, "`$1$NewVersion" | Write-Host
返回:118.11.8
预期:1.18.11.8
但是在$1
和$NewVersion
之间添加空格会产生不同但同样无济于事的结果。
$filecontent -replace $VersionReplacementRegex, "`$1 $NewVersion" | Write-Host
返回:1. 18.11.8
捕获的点出现在这里,但多余的空间也出现在这里。
那么,我想念的是什么?或者有更好的方法吗?
答案 0 :(得分:0)
从过去的经验来看,PetSerAl在对问题的评论中提供了关键的指针,不会回来发表答案。
tl; dr
如果将 -replace
与引用捕获组和 PowerShell 变量的替换操作数一起使用,请使用诸如"`${<ndx>}${<PsVar>}"
< / strong>,其中<ndx>
是捕获组的索引,而<PsVar>
是PowerShell变量的名称;请注意第一个`
之前的$
:
PS> $var = '2'; 'foo' -replace '(f)', "[`${1}$var]"
[f2]oo # OK, -replace saw '${1}2'
如果您忽略使用{...}
来消除捕获组索引的歧义,则替换操作会失败,因为插值的字符串值实际上会引用另一个索引:
-replace
然后会看到{{ 1}},由于引用了索引为[$12]
的不存在的捕获组,因此保持原样:
12
将PowerShell的字符串扩展(插值)与
PS> $var = '2'; 'foo' -replace '(f)', "[`$1$var]"
[$12]oo # !! -replace saw '$12', i.e., a nonexistent group with index 12
运算符的语法混合使用是很棘手的,因为它是容易混淆:
在双引号(-replace
)字符串中,PowerShell的通用 string扩展(字符串插值)功能可解释{{1} }字符 first ,其中"..."
前缀是指(PowerShell)变量,在$
内是整个语句
该扩展的结果是什么字符串,然后由$
运算符 then 解释,其中$(...)
前缀的标记是指正则表达式匹配操作的结果,如this answer所述。
请注意,-replace
的这些解释层是完全不相关的,并且两者都使用标记$
是偶然的。
因此:
如果您的替代操作数不需要需要字符串扩展,即,如果不需要引用PowerShell 变量或< em>表达式,请确保使用单引号字符串($
,这样PowerShell的字符串扩展就不会起作用:
$
如果您要做需要进行字符串扩展:
前缀'...'
字符。,应与 PS> 'foo' -replace '(f)', '[$1]'
[f]oo # OK - if you had used "[$1]" instead, the output would be '[]oo',
# because $1 is then interpreted as a *PowerShell variable*.
一起传递给$
-replace
(反引号)是PowerShell的常规转义字符,在`
字符串中,用于指示下一个字符将被 literally 接受;放在`
之前,它会抑制该标记的字符串内插;例如"..."
产生文字$
,即变量引用未 扩展。
要清除对捕获组的引用 ,例如,{strong},请将其包含在"I'm `$HOME"
中-例如I'm $HOME
$1
来消除 PowerShell 变量名称的歧义;例如{...}
必须为${1}
,才能成功引用变量{...}
。"$HOME1"
的替换操作数中,始终在捕获组索引/名称(和PS变量)周围使用"${HOME}1"
是形成的好习惯。 如果有疑问,请自行输出替换操作数,以检查$HOME
最终将看到什么。
"..."
(应用了字符串插值步骤)会使问题更加明显:{...}
为说明后一点:
-replace
问题在于,"[`$1$var]"
在字符串扩展后将[$12]
视为替换操作数,并且由于没有索引为PS> $var = '2'; 'foo' -replace '(f)', "[`$1$var]"
[$12]oo # !! $1 wasn't recognizes as the 1st capture group.
的捕获组,因此按原样保留它。
在-replace
中加上捕获组号可以解决此问题:
[$12]