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
其中 Index
和 Length
指定每个匹配项的位置。
但是,我找不到如何在使用 switch -regex
时获取每个匹配项的位置。例如:
switch -regex ('abcxyzabc') {
'abc(?<x>.*)abc' {
$matches
}
}
给出:
Name Value
---- -----
x xyz
0 abcxyzabc
我找不到像 Index
和 Length
这样的东西来获取 $matches
中的匹配位置。
我还检查了 Select-String -Pattern
返回的 Matches
类型是 System.Text.RegularExpressions.Match[]
,而 switch -regex
中 $matches
的类型是 System.Collections.Hashtable
。
我是不是错过了什么或者 switch -regex
不应该给出每个匹配项的位置?
最佳答案
Did I miss anything or is
switch -regex
not supposed to give the location of each match?
确实,switch
都不是语句的 -Regex
开关或(有效的)底层
-match
operator旨在通过 automatic $Matches
variable 提供除捕获的文本之外的信息 - 参见 this answer获取更多信息。
获取匹配-位置信息(起始索引,长度)需要以下之一:
Select-String
cmdlet,如您的问题所示。直接使用底层
[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's helpful answer向您展示了一种通过 switch
提供此功能的方式(有些麻烦)。
一种更有效的方法是结合 foreach
statement使用 if
语句:
foreach ($str in 'abcxyzabc', '...') {
if (($match = [regex]::Match($str, 'abc(?<x>.*)abc')).Success) { <# ... #> }
elseif (($match = [regex]::Match($str, 'cde(?<x>.*)cde')).Success) { <# ... #> }
# ...
}
关于regex - 是否可以使用 `switch -regex` 获取匹配位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68424481/