问题描述
试图简化一些PowerShell字符串替换代码,但遇到了我无法完全解释的内容。明确地说,我知道如何找到一个子字符串并将其替换/将其转换为另一个值。 我要问的是对此行为的解释,以及为什么这种行为不起作用。
使用常规字符串,无论是变量还是硬编码,我都可以在渲染字符串后修改其显示方式。例如:
($greeting = 'HELLO'.ToLower()) # ===> hello
这将通过返回字符串的小写形式来产生预期的输出。但是,我使用-replace
运算符进行了尝试,并得到了有趣的结果:
$greeting -replace '\w+','$0'.toupper() # ===> hello
我期望将字符串中的匹配模式替换为匹配的大写副本,但这没有发生。我尝试了其他一些越来越丑陋的方法,以查看是否有某种方法可以使它正常工作,但无济于事:
$greeting -replace '\w+',('$0').toupper() # ===> hello
$greeting -replace '\w+',"$(('$0').toupper())" # ===> hello
$greeting -replace '\w+',"`$0".toupper() # === hello
$greeting -replace '\w+','`$0'.ToString().toupper() # ===> hello
$greeting -replace '\w+',(('$0').ToString()).toupper() # ===> hello
我还尝试了-creplace
来代替-replace
,但其中的一些方法没有任何效果。为什么在使用PowerShell的-replace
运算符时无法转换匹配结果?
我使用PowerShell 5.1和PowerShell 7进行了测试,因此此行为在MS PowerShell和PowerShell Core之间扩展。
解决方法
ToUpper()
在之前执行,结果大写字符串作为替代参数传递给-replace
-$0
的大写版本为只是$0
,因此与完全省略.ToUpper()
没什么不同。
如果要ToUpper()
作为替代例程的一部分,则必须pass a scriptblock作为替代参数:
$greeting -replace '\w+',{$_.Value.ToUpper()}
这仅在PowerShell 6.2及更高版本中有效,在Windows PowerShell中,您必须直接调用[regex]::Replace()
:
[regex]::Replace($greeting,'\w+',{param($m) $m.Value.ToUpper()})