首页 > 解决方案 > 是否可以使用`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

我找不到任何类似的东西IndexLength$matches.

我还检查了Matches返回的类型Select-String -PatternSystem.Text.RegularExpressions.Match[],而$matchesin的类型switch -regexSystem.Collections.Hashtable

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

标签: regexpowershellswitch-statement

解决方案


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

实际上,语句的switch 和(有效的)底层运算符都不switch-Regex
-match
是为了通过自动$Matches变量提供捕获的文本以外的信息- 请参阅此答案以获取更多信息。

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

将后者应用于您的示例:

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) { <# ... #> }
  # ...
}

推荐阅读