我正在使用正则表达式替换来重命名文件:
ls *dat | rename-item -newname {$_.name -replace '(.*)_([0-9]+)(.dat)','$1($2)$3'}
但我还想向 [string]$2
添加一个 constant int
;类似的东西:
'$1(@{int.parse($2)+3})($3)'
我应该如何进行?
最佳答案
PowerShell Core v6.1.0+ 支持传递脚本 block 作为
的替换操作数
-替换
运算符;为找到的每个匹配项调用脚本 block ,其输出形成替换字符串,从而启用算法替换(而不仅仅是文本替换) :
'foo_10.dat' -replace '(.*)_([0-9]+)(\.dat)', {
'{0}{1}{2}' -f $_.Groups[1].Value,
([int] $_.Groups[2].Value + 3),
$_.Groups[3].Value
}
以上产量:
foo13.dat
请注意如何将 3
添加到 10
(并且删除了下划线):
$_
是 [System.Text.RegularExpressions.Match]
委托(delegate)比赛结果的实例;例如,$_.Value
表示完全匹配,而 $_.Groups[1].Value
表示第一个捕获组匹配的内容。
该功能基于 [regex]
.NET type's .Replace()
method 构建,它也可以在早期的 PowerShell 版本中直接使用(但不太容易) - 见下文。
在Windows PowerShell中,您有两个选项:
首先使用
-match
运算符,然后根据自动$Matches
变量中反射(reflect)的匹配信息在单独的语句中执行转换,如建议的通过 kuujinbo :$null = 'foo_10.dat' -match '(.*)_([0-9]+)(\.dat)' # match first '{0}{1}{2}' -f $Matches.1, ([int] $Matches.2 + 3), $Matches.3 # build via $Matches
直接使用 .NET 框架,并将脚本 block 作为委托(delegate)(回调函数)传递给上述
[regex]::Replace()
方法,如 Ansgar Wiechers 建议:([regex] '(.*)_([0-9]+)(\.dat)').Replace('foo_10.dat', { param($match) '{0}{1}{2}' -f $match.Groups[1].Value, ([int] $match.Groups[2].Value + 3), $match.Groups[3].Value })
- 请注意,必须在此处声明形式参数 -
param($match)
才能访问匹配结果,而顶部的纯 PowerShell 解决方案能够使用$ _
,像往常一样。
- 请注意,必须在此处声明形式参数 -
关于powershell - 如何在powershell中[int]添加[string]正则表达式替换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51505651/