我正在尝试将[regex]::Replace
与匹配评估器一起使用,以选择性地替换字符串的一部分。我正在编写和调试PowerShell ISE中的功能。奇怪的是,运行替换代码会使一台机器输出一个字符串,该字符串是匹配评估程序脚本块的内容,而另一台机器正确地替换了该文本。我完全不知道这是可能的,也不知道为什么会发生。
给出以下代码(从另一个stackoverflow答案中借用):
$global_counter = 0
$callback = {
$global_counter += 1
"string-$($args[0])-" + $global_counter
}
$re = [regex]"match"
$re.Replace('zzz match match xxx', $callback)
在一台机器上执行它会导致输出(PowerShell版本
5.1.18362.145
):zzz string-match-1 string-match-1 xxx
但是在另一个输出(PowerShell版本
5.1.17134.858
):zzz
$global_counter += 1
"string-$($args[0])-" + $global_counter
$global_counter += 1
"string-$($args[0])-" + $global_counter
xxx
两者都直接通过重新引导在x64 PowerShell ISE干净实例中运行。有人知道为什么会这样吗?
最佳答案
在Jeroen的调试帮助下,我设法弄清了为什么会这样。
PowerShell具有称为“约束语言模式”的安全功能,该功能可阻止使用任何(但是核心)白名单类型。似乎正在发生的事情是,我正在定义一个脚本块,然后将其传递给System.Text.RegularExpressions.MatchEvaluator
函数之前将其转换为Replace
。但是,匹配评估器不在此核心类型集中,这意味着当PowerShell引擎尝试将类型强制为Replace
重载时,唯一有效的另一个是Replace(string, string, string)
(感谢Jeroen在注释中指出了这一点)。 Replace
函数可以执行其工作,但是使用常规字符串作为替换,因此会导致异常行为。
通过组策略应用时,我无法在正在使用的计算机上更改PowerShell session 的语言模式,但至少可以使用一种提升的PowerShell session 和ISE测试我的解决方法,脚本。
关于powershell - 带有脚本 block 和正则表达式替换的奇怪Powershell行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59662506/