56

我在 C# 中有一个代码,它使用 lambda 表达式将委托传递给一个方法。如何在 PowerShell 中实现这一点。例如下面是一段 C# 代码:

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);

这是没有 lambda 表达式的 PowerShell 脚本:

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

注意:我的问题不是解决这个正则表达式问题。我只想知道如何将 lambda 表达式传递给在 PowerShell 中接收委托的方法。

4

3 回答 3

68

在 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(...)
于 2012-06-12T11:36:30.007 回答
26

有时你只想要这样的东西:

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

(它将声明一个匿名“函数”并立即调用它。)

于 2013-06-21T21:53:45.153 回答
16

你可以使用这个重载

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

委托作为脚本块(lambda 表达式)传递,并且可以通过 $args 变量访问 MatchEvaluator

[regex]::replace('hello world','hello', { $args[0].Value.ToUpper() })
于 2012-06-12T11:49:23.993 回答