2012-06-12 49 views
36

Tôi có một mã trong C# sử dụng các biểu thức lambda cho ủy nhiệm truyền vào một phương thức. Làm thế nào tôi có thể đạt được điều này trong PowerShell. Ví dụ sau đây là một mã C#:Biểu thức Lambda trong 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); 

Và đây là kịch bản PowerShell mà không lambda-biểu hiện tại chỗ:

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

Lưu ý: câu hỏi của tôi không phải là về giải quyết regular- này vấn đề biểu hiện. Tôi chỉ muốn biết cách truyền một biểu thức lambda đến một phương thức nhận các đại biểu trong PowerShell.

Trả lời

49

Trong PowerShell 2.0, bạn có thể sử dụng một khối kịch bản ({ some code here }) như đại biểu:

$MatchEvaluator = 
{ 
    param($m) 

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

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

Hoặc trực tiếp trong lời gọi phương thức:

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

Mẹo:

Bạn có thể sử dụng [regex] để chuyển đổi một chuỗi thành cụm từ thông dụng:

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

Và cảm ơn cũng đã đề cập đến cú pháp 'param ($ m)' bên trong các khối tập lệnh. –

+1

Nếu có ai thích ví dụ thực tế: '$ repo.Deployments.FindOne ({param ($ d) $ d.EnvironmentId -eq $ envId}); ' –

10

Bạn có thể sử dụng quá tải này

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

Các đại biểu là đi như một scriptblock (biểu thức lambda) và MatchEvaluator có thể được truy cập thông qua $ args biến

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

Bạn có thể sử dụng ScriptBlock thay cho bất kỳ đại biểu nào không? Tài liệu này ở đâu? –

+0

Nói chung, có. Tôi không biết bất kỳ tài liệu nào. –

+0

Cảm ơn tác phẩm này. Và +1 để đề cập đến mảng '$ args' bên trong khối tập lệnh. –

15

Đôi khi bạn chỉ muốn một cái gì đó như thế này:

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

(trong đó sẽ từ chối là một 'chức năng ẩn danh' và gọi nó ngay lập tức.)