是否可以使用`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
whereIndex和Length指定每个匹配的位置。
但是,在使用switch -regex. 例如:
switch -regex ('abcxyzabc') {
'abc(?<x>.*)abc' {
$matches
}
}
给出:
Name Value
---- -----
x xyz
0 abcxyzabc
我找不到像什么Index,并Length在拿到了赛位置$matches。
我还检查该类型Matches的返回Select-String -Pattern是System.Text.RegularExpressions.Match[],虽然类型$matches中switch -regex是System.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) { <# ... #> }
# ...
}