带有脚本块和正则表达式替换的奇怪Powershell行为

汤玛士

我正在尝试[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函数之前将其转换为a 但是,匹配评估器不在此核心类型集之内,这意味着当PowerShell引擎尝试将类型强制为Replace另一个唯一有效类型的重载时Replace(string, string, string)(感谢Jeroen在注释中指出)。Replace函数完成其工作,但使用常规字符串作为替换,从而导致异常行为。

通过组策略应用时,我无法在正在使用的计算机上更改PowerShell会话的语言模式,但至少可以使用一种提升的PowerShell会话和ISE测试我的解决方法,脚本。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章