2012-06-12 15 views
36

Mam kod w języku C#, który używa wyrażeń lambda dla przekazania przekazania do metody. Jak mogę to osiągnąć w PowerShell? Na przykład po to kod C#:Wyrażenie Lambda w 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); 

I to jest skrypt PowerShell bez lambda wyrażenia w lokalu:

$input = "(,)(;)(:)(!)"; 
$pattern = "\((?<val>[\,\!\;\:])\)"; 
$r = New-Object System.Text.RegularExpressions.Regex $pattern 
$result = $r.Replace($input, "WHAT HERE?") 
Write-Host $result 

Uwaga: moje pytanie nie jest o rozwiązaniu tego regular- problem z ekspresją. Po prostu chcę wiedzieć, jak przekazać wyrażenie lambda do metody, która otrzymuje delegatów w PowerShell.

Odpowiedz

49

W PowerShell 2.0 można użyć bloku skryptu ({ some code here }) jako delegat:

$MatchEvaluator = 
{ 
    param($m) 

    if ($m.Groups["val"].Value -eq ";") 
    { 
    #... 
    } 
} 

$result = $r.Replace($input, $MatchEvaluator) 

lub bezpośrednio w wywołaniu metody:

$result = $r.Replace($input, { param ($m) bla }) 

Wskazówka:

Można użyj [regex], aby przekonwertować ciąg znaków na wyrażenie regularne:

$r = [regex]"\((?<val>[\,\!\;\:])\)" 
$r.Matches(...) 
+4

Dziękuję również za wspomnienie składni "param ($ m)" wewnątrz bloków skryptu. –

+1

Jeśli ktoś chciałby prawdziwego przykładu: '$ repo.Deployments.FindOne ({param ($ d) $ d.EnvironmentId -eq $ envId});' –

10

Można użyć tej przeciążenie

[regex]::replace(
    string input, 
    string pattern, 
    System.Text.RegularExpressions.MatchEvaluator evaluator 
) 

Delegat to przechodzi jako scriptblock (wyrażenie lambda) i MatchEvaluator mogą być dostępne za pośrednictwem $ args zmiennej

[regex]::replace('hello world','hello', { $args[0].Value.ToUpper() }) 
+1

Czy możesz użyć ScriptBlock zamiast dowolnego delegata? Gdzie jest to udokumentowane? –

+0

Ogólnie mówiąc, tak. Nie znam żadnej dokumentacji. –

+0

Dzięki temu działa. I +1 za wymienienie tablicy '$ args' wewnątrz bloku skryptu. –

15

czasami po prostu chcesz coś takiego:

{$args[0]*2}.invoke(21) 

(która zostanie odrzucona są anonimową "funkcją" i wywołują ją natychmiast.)

Powiązane problemy