对字符串应用正则表达式过滤器,该字符串在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

我想构建一个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
的内容,然后查找第一个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'