2012-06-12 13 views
36

Tengo un código en C# que usa expresiones lambda para delegar pasar a un método. ¿Cómo puedo lograr esto en PowerShell? Por ejemplo, el siguiente es un código C#:Expresión lambda en 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); 

Y este es el script de PowerShell sin el lambda-expresión en su lugar:

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

Nota: mi pregunta no se trata de resolver este regular- problema de expresión Solo quiero saber cómo pasar una expresión lambda a un método que recibe delegados en PowerShell.

Respuesta

49

En PowerShell 2.0 se puede utilizar un bloque de script ({ some code here }) como delegado:

$MatchEvaluator = 
{ 
    param($m) 

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

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

o directamente en la llamada al método:

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

Consejo:

Puede use [regex] para convertir una cadena en una expresión regular:

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

Y gracias también por mencionar la sintaxis 'param ($ m)' dentro de los bloques de script. –

+1

Si alguien quisiera un ejemplo real: '$ repo.Deployments.FindOne ({param ($ d) $ d.EnvironmentId -eq $ envId});' –

10

Puede utilizar esta sobrecarga

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

El delegado es pasa como ScriptBlock (expresión lambda) y el MatchEvaluator puede acceder a través del $ args variables

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

¿Se puede utilizar un ScriptBlock en lugar de cualquier delegado? ¿Dónde está esto documentado? –

+0

Hablando en general, sí. No conozco ninguna documentación. –

+0

Gracias esto funciona. Y +1 por mencionar la matriz '$ args' dentro del bloque de script. –

15

veces sólo quiere algo como esto:

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

(que se declinará son una 'función' anónima y la llaman inmediatamente.)