2012-06-12 23 views
36

Ho un codice in C# che utilizza espressioni lambda per il passaggio delegato a un metodo. Come posso ottenerlo in PowerShell. Ad esempio, il seguente è un codice C#:Espressione lambda in 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); 

E questo è lo script PowerShell senza il lambda-espressione in atto:

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

Nota: la mia domanda non è di risolvere questo regolarizzazione problema di espressione. Voglio solo sapere come passare un'espressione lambda a un metodo che riceve i delegati in PowerShell.

risposta

49

In PowerShell 2.0 è possibile utilizzare un blocco di script ({ some code here }) come delegato:

$MatchEvaluator = 
{ 
    param($m) 

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

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

O direttamente nella chiamata di metodo:

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

Suggerimento:

Puoi utilizzare [regex] per convertire una stringa in un'espressione regolare:

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

E grazie anche per aver menzionato la sintassi 'param ($ m)' all'interno dei blocchi di script. –

+1

Se qualcuno desidera un esempio reale: '$ repo.Deployments.FindOne ({param ($ d) $ d.EnvironmentId -eq $ envId});' –

10

È possibile utilizzare questo sovraccarico

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

Il delegato è passa come uno scriptblock (espressione lambda) e il MatchEvaluator si può accedere tramite il $ args variabile

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

È possibile utilizzare uno ScriptBlock al posto di qualsiasi delegato? Dove è documentato? –

+0

In generale, si. Non sono a conoscenza di alcuna documentazione. –

+0

Grazie a questo funziona. E +1 per menzionare l'array '$ args' all'interno del blocco di script. –

15

A volte basta desidera qualcosa del genere:

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

(che decl sono una "funzione" anonima e chiamiamola immediatamente)