C# 在脚本文件中搜索参数

C# 在脚本文件中搜索参数,c#,regex,powershell,C#,Regex,Powershell,我正在寻找一种在C中搜索PowerShell脚本文件以查找其参数的方法 我的PowerShell脚本顶部包含以下内容: [CmdletBinding()] param( [Parameter(Position=1, Mandatory=$true)] [string]$Domain, [Parameter(Position=2, Mandatory=$true)] [string]$SIPDomain, [Parameter(Position=3, Mand

我正在寻找一种在C中搜索PowerShell脚本文件以查找其参数的方法

我的PowerShell脚本顶部包含以下内容:

 [CmdletBinding()]  
    param(
    [Parameter(Position=1, Mandatory=$true)] [string]$Domain,
    [Parameter(Position=2, Mandatory=$true)] [string]$SIPDomain,
    [Parameter(Position=3, Mandatory=$true)] [string]$RegistrarPool,
    [Parameter(Position=4, Mandatory=$true)] [string]$ExchangeServer,
    [Parameter(Position=5, Mandatory=$true)] [string]$OU,  
    [Parameter(Position=6, Mandatory=$false)] [string]$SleepTime="10",
    [Parameter(Position=7, Mandatory=$false)] [bool]$CreateAA=$true,
    [Parameter(Position=8, Mandatory=$false)] [bool]$CreateSA=$true
    ) 
对于每个参数,我想存储它的位置,无论它是强制性的,类型,变量名和默认值(如果有)。我也希望所有的变量,但必须作为一些脚本可能有非常基本的参数,例如

param($name, $test)
对于上面的示例,我想要一个如下所示的对象:

将强制类型变量DefaultValuePosition置于“=”后面的位

1 $true String $Domain
2 $true String $SIPDomain
3 $true String $RegistrarPool
4 $true String $ExchangeServer
5 $true String $OU
6 $false String $SleepTime 10
7 $false bool $CreateAA $true
8 $false bool $CreateSA $true
我花了几个小时试图使用regex获得正确的分割,但我认为模式对我来说有点太复杂了

非常感谢你在这方面的帮助

谢谢, Andrew

这只适用于V3:

(@'
[CmdletBinding()]  
    param(
    [Parameter(Position=1, Mandatory=$true)] [string]$Domain,
    [Parameter(Position=2, Mandatory=$true)] [string]$SIPDomain,
    [Parameter(Position=3, Mandatory=$true)] [string]$RegistrarPool,
    [Parameter(Position=4, Mandatory=$true)] [string]$ExchangeServer,
    [Parameter(Position=5, Mandatory=$true)] [string]$OU,  
    [Parameter(Position=6, Mandatory=$false)] [string]$SleepTime="10",
    [Parameter(Position=7, Mandatory=$false)] [bool]$CreateAA=$true,
    [Parameter(Position=8, Mandatory=$false)] [bool]$CreateSA=$true
    )
'@).split("`n") |
foreach {$_.trim()} | sc testparams.ps1

$AST = [System.Management.Automation.Language.Parser]::
ParseFile('c:\testfiles\testparams.ps1',[ref]$null,[ref]$null)

$AST.ParamBlock.Parameters | 
 foreach {
   $IsMandatory = $_.Extent.Text -match 'Mandatory=\$true'
   $Position = $_.Extent.Text -replace '.+Position=(\d+).+','$1'
   New-Object PSObject -Property @{
                                    Name = $_.Name
                                    Type = $_.StaticType
                                    Position = $Position
                                    Mandatory = $IsMandatory
                                    }
        } | Select Name,Type,Position,Mandatory | ft -auto

Name            Type           Position Mandatory
----            ----           -------- ---------
$Domain         System.String  1             True
$SIPDomain      System.String  2             True
$RegistrarPool  System.String  3             True
$ExchangeServer System.String  4             True
$OU             System.String  5             True
$SleepTime      System.String  6            False
$CreateAA       System.Boolean 7            False
$CreateSA       System.Boolean 8            False

您可以使用以下代码获得指定的相同输出:

var matches = Regex.Matches(script, @"\s*\[Parameter\(.*?\)\].*?,");

foreach (var match in matches)
{
    string result = Regex.Replace(match.ToString().Trim(), @".*Position=(.*?),\s*Mandatory=(.*?)\).*?\[(.*?)\](.*?)(=""(.*?)""|\s*),", "$1 $2 $3 $4 $6");
    Console.WriteLine(result);
}
这首先匹配包含参数模式的行。然后,它为每一行提取所需的输出

更新 要将数据转换为变量,请在foreach循环中使用以下行:


然后使用datamatch.Groups[1]、datamatch.Groups[2]等获取字符串,然后将字符串解析为所需的类型。例如,对于整数,请使用int.Parse

您使用的powershell版本是什么?在本例中是3.0,但有时我会使用2.0,具体取决于我管理的MS产品版本。这看起来对PS很有效,但我希望在从.ps1脚本读取参数的C应用程序中进行查询。抱歉,我只知道PS。AST解析器应该可以在C中使用,但我不能给你这方面的代码。我会删除答案,如果它没有帮助。谢谢你的帮助,这是非常接近!!!输出如下:=1$true string$Domain=2$true string$SIPDomain=3$true string$registerpool=4$true string$ExchangeServer。只需要去掉位置号前面的“=”。我还可以很容易地将数据输入到对象/表变量/数组中,以便以后可以提取数据吗?如果术语不好,道歉。我来自PowerShell的背景,我正在学习C.@AndrewMorpeth我有一个打字错误,忘记了=。现在已经修好了。此外,更新了关于如何在变量中获取它们的答案。我不能完全理解表位。我如何存储在一个看起来像原始帖子中的表的对象变量中?标题:位置、强制、类型、变量、,DefaultValue@AndrewMorpeth我离开了一段时间,但是,如果您仍然需要,有许多不同的方法来存储数据,您可以使用一个结构/类数组来封装行中的所有字段,这对于将所有相关/相关数据存储在一起非常有用,或者您可以有一个特定键位置/变量名的字典,该值将是封装其他值的结构,这在按键索引/搜索时非常有用。。。下一节继续comment@AndrewMorpeth或者,您可以有多个数组,每个数据字段一个数组,位置数组,强制数组,等等,这对于获取每个字段数据的统计信息非常有用,但如果需要,您应该找到附加相关数据的方法。根据您的应用程序,还有其他方法。对于解析,您必须确定每个字段int/bool/string/…的数据类型。。。然后使用内置的字符串类型解析方法对其进行解析。
 var datamatch = Regex.Match(match.ToString().Trim(), @".*Position=(.*?),\s*Mandatory=(.*?)\).*?\[(.*?)\](.*?)(=""(.*?)""|\s*),");