2012-06-12 33 views
36

我在C#中有一個代碼,它使用lambda表達式將委託傳遞給一個方法。我如何在PowerShell中實現這一點。例如,下面是一個C#代碼:Powershell中的Lambda表達式

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腳本:

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

注:我的問題是不是解決這個regular-表達問題。我只想知道如何將一個lambda表達式傳遞給在PowerShell中接收委託的方法。

回答

49

在PowerShell 2.0中,你可以使用腳本塊({ 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(...) 
+4

而且還要感謝在腳本塊中提到'param($ m)'語法。 –

+1

如果有人想要一個真正的例子:'$ repo.Deployments.FindOne({param($ d)$ d.EnvironmentId -eq $ envId});' –

10

您可以使用此重載

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

的代表是通過一個腳本塊(lambda表達式)和MatchEvaluator可以通過$ args變量

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

您可以使用ScriptBlock代替任何代理嗎?這在哪裏記錄? –

+0

一般來說,是的。我不知道任何文檔。 –

+0

感謝這工作。並在腳本塊中提及'$ args'數組+1。 –

15

有時候,只是來訪問你想要這樣的事情:

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

(它會解除是一個匿名的'函數',並立即調用它。)