是否可以使用`switch-regex`获得匹配位置

Select-String -Pattern返回每个匹配的位置。例如:

$s = 'abcxyzabc' | Select-String -Pattern 'abc(?<x>.*)abc'
$s.Matches[0].Groups | Select-Object Name, Value, Index, Length

给出:

Name Value     Index Length
---- -----     ----- ------
0    abcxyzabc     0      9
x    xyz           3      3

whereIndexLength指定每个匹配的位置。

但是,在使用switch -regex. 例如:

switch -regex ('abcxyzabc') {
    'abc(?<x>.*)abc' {
        $matches
    }
}

给出:

Name                           Value
----                           -----
x                              xyz
0                              abcxyzabc

我找不到像什么Index,并Length在拿到了赛位置$matches

我还检查该类型Matches的返回Select-String -PatternSystem.Text.RegularExpressions.Match[],虽然类型$matchesswitch -regexSystem.Collections.Hashtable

我是否错过了什么或switch -regex不应该提供每场比赛的位置?

回答

我是否错过了什么或switch -regex不应该提供每场比赛的位置?

事实上,无论是switch语句的-Regexswitch 还是(有效的)底层
-match运算符,都没有被设计为
通过自动$Matches变量提供除捕获的文本之外的信息-有关更多信息,请参阅此答案。

获取匹配位置信息(起始索引、长度)需要以下条件之一:

  • Select-Stringcmdlet时,在你的问题,如图所示。

  • 直接使用底层[regex]类 ( System.Text.RegularExpressions.Regex)。

将后者应用于您的示例:

PS> [regex]::Match('abcxyzabc', 'abc(?<x>.*)abc')

Groups   : {0, x}
Success  : True
Name     : 0
Captures : {0}
Index    : 0
Length   : 9
Value    : abcxyzabc

Daniel 的有用回答向您展示了通过switch.

一种更有效的方法是将foreach语句与if语句结合起来:

foreach ($str in 'abcxyzabc', '...') {
  if     (($match = [regex]::Match($str, 'abc(?<x>.*)abc')).Success) { <# ... #> }
  elseif (($match = [regex]::Match($str, 'cde(?<x>.*)cde')).Success) { <# ... #> }
  # ...
}


以上是是否可以使用`switch-regex`获得匹配位置的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>