Лямбда-выражение в Powershell
У меня есть код в С#, который использует лямбда-выражения для передачи делегата методу. Как я могу добиться этого в PowerShell. Например, следующий код С#:
string input = "(,)(;)(:)(!)";
string pattern = @"\((?<val>[\,\!\;\:])\)";
var r = new Regex(pattern);
string result = r.Replace(input, m =>
{
if (m.Groups["val"].Value == ";") return "[1]";
else return "[0]";
});
Console.WriteLine(result);
И это PowerShell script без лямбда-выражения на месте:
$input = "(,)(;)(:)(!)";
$pattern = "\((?<val>[\,\!\;\:])\)";
$r = New-Object System.Text.RegularExpressions.Regex $pattern
$result = $r.Replace($input, "WHAT HERE?")
Write-Host $result
Примечание: мой вопрос не в решении этой проблемы с регулярным выражением. Я просто хочу знать, как передать лямбда-выражение методу, который принимает делегатов в PowerShell.
Ответы
Ответ 1
В PowerShell 2.0 вы можете использовать блок script ({ some code here }
) в качестве делегата:
$MatchEvaluator =
{
param($m)
if ($m.Groups["val"].Value -eq ";")
{
#...
}
}
$result = $r.Replace($input, $MatchEvaluator)
Или непосредственно в вызове метода:
$result = $r.Replace($input, { param ($m) bla })
Совет:
Вы можете использовать [regex]
для преобразования строки в регулярное выражение:
$r = [regex]"\((?<val>[\,\!\;\:])\)"
$r.Matches(...)
Ответ 2
Иногда вам просто нужно что-то вроде этого:
{$args[0]*2}.invoke(21)
(который объявит анонимную "функцию" и вызовет ее немедленно.)
Ответ 3
Вы можете использовать эту перегрузку
[regex]::replace(
string input,
string pattern,
System.Text.RegularExpressions.MatchEvaluator evaluator
)
Делегат проходит как скриптовый блок (выражение лямбда), а доступ к MatchEvaluator можно получить через переменную $args
[regex]::replace('hello world','hello', { $args[0].Value.ToUpper() })