可选非捕获组中的命名捕获组

Named capture group within optional non-capturing group

我有以下 PowerShell 代码:

$input = 'ADM:Dev_ControllerStore_103:1:2'
$pattern = '^(?<UID>\S+)\:(?<DB>\S+)\:(?<AppId>\d+)(?:\:(?<LicNr>\d+))?$'
if ( $input -match $pattern ) {
    $Matches
}

这给出了以下输出:

Name                           Value
----                           -----
DB                             1
AppId                          2
UID                            ADM:Dev_ControllerStore_103
0                              ADM:Dev_ControllerStore_103:1:2

虽然我希望如此:

Name                           Value
----                           -----
DB                             1
AppId                          2
UID                            ADM:Dev_ControllerStore_103
LicNr                          2
0                              ADM:Dev_ControllerStore_103:1:2

LicNr 包含在输出中。

注意:我得到的输出是输入字符串的预期输出:'ADM:Dev_ControllerStore_103:1' ... 并且工作正常。

如果我更改正则表达式使最后一个非捕获组成为非可选组,或者我删除了非捕获组,那么对于较长的输入字符串都可以正常工作;但显然这些不适合只有 3 个值而不是 4 个值的版本。​​

我是不是遗漏了什么,或者这是 PowerShell 中的错误?

注意:我有一个解决方法(~$a,$b,$c,$d = $input -split ':'),所以这个问题只是出于学术兴趣。

\S 模式匹配任何非空白字符,包括 : 和数字。您可以使用惰性 \S+? 模式 '^(?<UID>\S+?):(?<DB>\S+?):(?<AppId>\d+)(?::(?<LicNr>\d+))?$' 来修复模式,但也可以使用更精确的模式,该模式将使用更适合您的输入的模式:

^(?<UID>\w+):(?<DB>\w+):(?<AppId>\d+)(?::(?<LicNr>\d+))?$

regex demo

详情

  • ^ - 字符串开头
  • (?<UID>\w+) - 组 UID:一个或多个字符
  • : - 冒号
  • (?<DB>\w+) - 组数据库:一个或多个单词字符
  • : - 冒号
  • (?<AppId>\d+) - 组AppId:一位或多位
  • (?::(?<LicNr>\d+))? - 一个可选组:a : 然后是 Group LicNr: 1+ digits
  • $ - 字符串结尾。

因为你想在 : 上拆分并在最后有一个可选部分,所以让你的量词在该选项之前是非贪婪的:

$input = 'ADM:Dev_ControllerStore_103:1:2'
$pattern = '^(?<UID>\S+?)\:(?<DB>\S+?)\:(?<AppId>\d+?)(?:\:(?<LicNr>\d+))?$'
if ( $input -match $pattern ) {
    $Matches
}

输出:

Name                           Value                                                                  
----                           -----                                                                  
DB                             Dev_ControllerStore_103                                                
AppId                          1                                                                      
UID                            ADM                                                                    
LicNr                          2                                                                      
0                              ADM:Dev_ControllerStore_103:1:2