为什么我不能在 PowerShell 的替换运算符中转换匹配令牌?
Why can't I transform the match token in PowerShell's replace operator?
试图简化一些 PowerShell 字符串替换代码,遇到了一些我无法解释的问题。明确地说,我知道如何找到一个子字符串并将 it/transform 替换为另一个值。 我在这里要求的是对这种行为的解释以及为什么它不能这样工作。
对于常规字符串,无论它是变量还是硬编码,我都可以在呈现后按照我认为合适的方式修改字符串。例如:
($greeting = 'HELLO'.ToLower()) # ===> hello
这通过返回字符串的小写副本产生预期的输出。但是,我使用 -replace
运算符进行了尝试,得到了一个有趣的结果:
$greeting -replace '\w+', '[=11=]'.ToUpper() # ===> hello
我原以为字符串中的匹配模式会被替换为匹配项的大写副本,但这并没有发生。我尝试了其他一些越来越丑陋的方法,看看是否有某种方法可以让它工作但无济于事:
$greeting -replace '\w+', ('[=12=]').ToUpper() # ===> hello
$greeting -replace '\w+', "$(('[=12=]').ToUpper())" # ===> hello
$greeting -replace '\w+', "`[=12=]".ToUpper() # === hello
$greeting -replace '\w+', '`[=12=]'.ToString().ToUpper() # ===> hello
$greeting -replace '\w+', (('[=12=]').ToString()).ToUpper() # ===> hello
我也尝试用 -creplace
代替 -replace
来处理其中的一些,但这也没有任何效果。为什么在使用 PowerShell 的 -replace
运算符时无法转换匹配结果?
我使用 PowerShell 5.1 和 7 对此进行了测试,因此此行为在 MS PowerShell 和 PowerShell Core 之间扩展。
ToUpper()
在 之前执行 结果 upper-case 字符串作为替代参数传递给 -replace
- 而 upper-case 版本的 [=14=]
只是 [=14=]
,因此与完全省略 .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()})
试图简化一些 PowerShell 字符串替换代码,遇到了一些我无法解释的问题。明确地说,我知道如何找到一个子字符串并将 it/transform 替换为另一个值。 我在这里要求的是对这种行为的解释以及为什么它不能这样工作。
对于常规字符串,无论它是变量还是硬编码,我都可以在呈现后按照我认为合适的方式修改字符串。例如:
($greeting = 'HELLO'.ToLower()) # ===> hello
这通过返回字符串的小写副本产生预期的输出。但是,我使用 -replace
运算符进行了尝试,得到了一个有趣的结果:
$greeting -replace '\w+', '[=11=]'.ToUpper() # ===> hello
我原以为字符串中的匹配模式会被替换为匹配项的大写副本,但这并没有发生。我尝试了其他一些越来越丑陋的方法,看看是否有某种方法可以让它工作但无济于事:
$greeting -replace '\w+', ('[=12=]').ToUpper() # ===> hello
$greeting -replace '\w+', "$(('[=12=]').ToUpper())" # ===> hello
$greeting -replace '\w+', "`[=12=]".ToUpper() # === hello
$greeting -replace '\w+', '`[=12=]'.ToString().ToUpper() # ===> hello
$greeting -replace '\w+', (('[=12=]').ToString()).ToUpper() # ===> hello
我也尝试用 -creplace
代替 -replace
来处理其中的一些,但这也没有任何效果。为什么在使用 PowerShell 的 -replace
运算符时无法转换匹配结果?
我使用 PowerShell 5.1 和 7 对此进行了测试,因此此行为在 MS PowerShell 和 PowerShell Core 之间扩展。
ToUpper()
在 之前执行 结果 upper-case 字符串作为替代参数传递给 -replace
- 而 upper-case 版本的 [=14=]
只是 [=14=]
,因此与完全省略 .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()})