Странное поведение powershell с блоками скриптов и заменой регулярных выражений - PullRequest
2 голосов
/ 09 января 2020

Я пытаюсь использовать [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 Version 5.1.17134.858):

zzz
    $global_counter += 1
    "string-$($args[0])-" + $global_counter

    $global_counter += 1
    "string-$($args[0])-" + $global_counter
 xxx

Оба работают в чистом экземпляре PowerShell ISE x64 непосредственно после перезагрузки , Кто-нибудь знает, почему это происходит?

1 Ответ

1 голос
/ 09 января 2020

С помощью справки по отладке от Jeroen мне удалось выяснить, почему это происходит.

PowerShell имеет функцию безопасности, называемую режим ограниченного языка, которая предотвращает использование любого, кроме основного набора типов из белого списка. Похоже, происходит то, что я определяю блок скриптов, который, в свою очередь, преобразуется в System.Text.RegularExpressions.MatchEvaluator перед передачей в функцию Replace. Однако оценщик совпадений находится за пределами этого основного набора типов, что означает, что когда механизм PowerShell пытается принудительно привести тип к перегрузке Replace, единственным другим допустимым является Replace(string, string, string) (спасибо Jeroen за указание на это в комментариях) , Функция Replace выполняет свою работу, но с обычной строкой в ​​качестве замены, что приводит к странному поведению.

Я не могу изменить языковой режим сеанса PowerShell на компьютере, на котором я работаю в настоящее время работает с тем, как оно применяется через групповые политики, но обходной путь для меня, по крайней мере, заключался в использовании повышенного сеанса PowerShell и ISE для тестирования моего сценария.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...