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

标签 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。但是,匹配评估器不在此核心类型集中,这意味着当PowerShell引擎尝试将类型强制为Replace重载时,唯一有效的另一个是Replace(string, string, string)(感谢Jeroen在注释中指出了这一点)。 Replace函数可以执行其工作,但是使用常规字符串作为替换,因此会导致异常行为。

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

关于powershell - 带有脚本 block 和正则表达式替换的奇怪Powershell行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59662506/

相关文章:

sql-server - SQL Server Powershell错误:在此计算机上找不到Invoke-SqlCmd命令

powershell - 使用参数在while循环中将值传递给开关

powershell - 在 PowerShell 中比较 '1' 和 '_' 会产生意外结果

windows - 为什么 power shell clear(或 cls)命令接受数字作为参数?

powershell - 使用powershell检索txt文件中的内容

windows - 将 powershell 输出导出到文本文件

powershell - 如何从 PowerShell 中的 SFTP 服务器删除早于 x 天的文件

c++ - 如何从 PowerShell 获取 CreateTransaction 地址

json - 通过 webhook 和 PS 脚本触发的 MS Teams 警报不想解析多行文本

linq - 在 PowerShell 中查询 LINQ 样式的列表