String Regex接受命令并拆分命令、参数和参数值
下午好 我想我在这项特殊任务上有点不知所措。我试图创建一个正则表达式匹配函数来输入命令,并将命令名、参数和参数值拆分 新变量-名称Something-Force 结果应该是String Regex接受命令并拆分命令、参数和参数值,string,powershell,parsing,command-line-arguments,String,Powershell,Parsing,Command Line Arguments,下午好 我想我在这项特殊任务上有点不知所措。我试图创建一个正则表达式匹配函数来输入命令,并将命令名、参数和参数值拆分 新变量-名称Something-Force 结果应该是 新变量 -名字 某物 -强迫 到目前为止,我已经提出了这个,但它只捕获了第一个参数集 奖励:有没有办法在递增命名的命令之后进行所有匹配?说出参数1、值1、参数2、值2等 ^(?P<Command>[a-zA-Z]+-[a-zA-Z]+)(?: +)((-\S+)(?: |:|=)(.*){0,1})(?: +)
^(?P<Command>[a-zA-Z]+-[a-zA-Z]+)(?: +)((-\S+)(?: |:|=)(.*){0,1})(?: +)
不要为此使用正则表达式-请改用内置解析器:
# Prepare command to parse
$command = 'New-Variable -Name Something -Force'
# Parse command invocation - Parser will return an Abstract Syntax Tree object
$parserErrors = @()
$AST = [System.Management.Automation.Language.Parser]::ParseInput($command, [ref]$null, [ref]$parserErrors)]
if($parserErrors){
# error encountered while parsing script
}
else {
# No errors, let's search the AST for the first command invocation
$CommandInvocation = $AST.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false)
# Get the string representation of each syntax element in the command invocation
$elements = $CommandInvocation.CommandElements |ForEach-Object ToString
}
通过您的输入(New Variable-Name Something-Force
),它将生成以下字符串:
PS ~> $elements
New-Variable
-Name
Something
-Force
注意:使用
:
紧密绑定到参数的参数将被解释为单个连体语法元素,例如,“Get Thing-Name:nameOfThing”将只生成两个字符串(Get Thing
和-Name:nameOfThing
)-如果希望将它们拆分为单独的字符串,在将它们转换为字符串之前,请考虑这一点:
$elements = $CommandInvocation.CommandElements |ForEach-Object {
if($null -ne $_.Argument){
# tightly bound argument, output both separately
"-$($_.ParameterName)"
$_.Argument
} else {
# just the parameter name, output as-is
$_
}
} |ForEach-Object ToString
以简化的解决方案作为补充,假设:
- 您只需要对表示命令名及其参数的字符串数组感兴趣
- 字符串表示语法上有效的命令,即不必担心错误处理
$tokenStrings
然后包含一个包含逐字元素的字符串数组
新变量
,-Name
,某物
,-Force
另见:
- PowerShell的语言解析器类
-param:arg
表示为单个字符串,则不需要它,但如果希望严格分隔参数名称和参数,则它是:-)我的意思是,当我传递-Parameter:value时,它会将它们分隔开。
$elements = $CommandInvocation.CommandElements |ForEach-Object {
if($null -ne $_.Argument){
# tightly bound argument, output both separately
"-$($_.ParameterName)"
$_.Argument
} else {
# just the parameter name, output as-is
$_
}
} |ForEach-Object ToString
$stringToParse = 'New-Variable -Name Something -Force'
$tokens = $null # Initialize the output variable.
# Parse the string as a PowerShell command.
$null = [System.Management.Automation.Language.Parser]::ParseInput(
$stringToParse,
[ref] $tokens, # will receive a collection of tokens
[ref] $null # would receive a collection of parsing errors; unused here
)
$tokenStrings = $tokens.Text -ne '' # -ne '' ignores the end-of-input token