对字符串应用正则表达式过滤器,该字符串在powershell中给定字符出现后返回值
我想构建一个PowerShell脚本,它在字符串中第一次出现给定字符后返回短语。例如,我想获得第一次出现对字符串应用正则表达式过滤器,该字符串在powershell中给定字符出现后返回值,powershell,Powershell,我想构建一个PowerShell脚本,它在字符串中第一次出现给定字符后返回短语。例如,我想获得第一次出现v字符后的所有短语: blah_v1.2 foo_v1 vbarv_2.4 bar 结果将是 1.2 1 barv_2.4 我尝试过构建类似的东西,但是$FooVersion返回的是布尔值而不是字符串 $Foo = "blah_v1.1" $FooVersion = $Foo -match "_v (.*)" Write-Host $Foo Write-Host $FooVersion
v
字符后的所有短语:
blah_v1.2
foo_v1
vbarv_2.4
bar
结果将是
1.2
1
barv_2.4
我尝试过构建类似的东西,但是$FooVersion返回的是布尔值而不是字符串
$Foo = "blah_v1.1"
$FooVersion = $Foo -match "_v (.*)"
Write-Host $Foo
Write-Host $FooVersion
有什么想法吗?干杯确保查找所有不是
v
的内容,然后查找第一个v,然后从$Matches
变量中获取捕获的值:
$strings = -split @'
blah_v1.2
foo_v1
vbarv_2.4
bar
'@
$strings |ForEach-Object {
if($_ -match '[^v]*v(.*)'){
$Matches[1]
}
}
尝试一些可能性:
$Foo = "blah_v1.1"
# using -replace
# returns a string without 'v' as-is
$FooVersion = $Foo -replace '(?:[^v]*v)(.*)', '$1'
或
或
将与输入字符串数组一起使用可提供简洁的解决方案:
# Sample input lines (string array)
$lines = @'
blah_v1.2
foo_v1
vbarv_2.4
bar
'@ -split '\r?\n'
# Perform a regex-based string replacement on each input line,
# so as to only extract the substrings of interest.
$lines -replace '.*?v(.*)', '$1'
上述收益率:
1.2
1
barv_2.4
bar
给定一个数组作为LHS,-replace
逐个操作数组的元素
Regex*?v(.*)
非贪婪地(?
)匹配任何(*
)到第一个v
,然后(贪婪地)捕获捕获组((…)
)中$1
后的任何内容,替换操作数中的$1
指该捕获组,由于正则表达式匹配整个输入字符串,因此输出是输入中第一个v
之后的任何内容
请注意,-replace
按原样将与正则表达式不匹配的输入传递给,这就是为什么不包含v
的条也出现在输出中的原因;如果要省略不带v
的行,如示例输出中所示:
@($lines) -match 'v' -replace '.*?v(.*)', '$1'
请注意@(…)
周围的$lines
,这确保了LHS始终被视为一个数组,因为-match
仅充当具有数组值LHS的过滤器,而不是单个输入字符串(见下文)。
(根据定义,上面的示例输入是一个数组,但是如果您从带有Get Content
的文件加载行,例如,单行输入文件将生成一个字符串,而不是一个1元素数组。)
-match'v'
因此返回包含字母v
的$line
元素的子数组,该子数组-replace
然后对其进行操作
注:
- 数组+
-replace
方法对于已经在内存中的集合既方便又快速
- 如果需要在管道中执行更换,请使用
- 这就是说,如果您知道您的输入集可以作为一个整体装入内存,那么可以通过在表达式(
(…)
中捕获管道(cmdlet)输出来提高性能,或者,为了保证一个数组,@(…)
)可以再次对其应用-replace
:
@(Get Content input.txt)-替换“.*?v(.*)”,$1'
至于你所尝试的:
对于标量LHS,-match
返回一个布尔值(指示输入是否匹配),正如您所经历的那样
但是,使用标量LHS(仅限!),PowerShell会使用匹配((子)字符串匹配(条目0
)、捕获组值(条目1
用于第一个捕获组,…)的详细信息填充自动$Matches
哈希表,因此您可以在以后使用它,如中所示。做得很好;您可以将正则表达式稍微简化为v(.*)
(*
的贪婪性将确保只匹配第一个v
)。最后我明白了*?
;)的意思
1.2
1
barv_2.4
bar
@($lines) -match 'v' -replace '.*?v(.*)', '$1'