我有这个perl代码我试图转换为powershell。
foreach my $f ( @file_list ) {
if( $f =~ /^([\d]+)_${base_ver}_([\d]{4})\.zip$/i ){
$pfile = $f;
( $pnum, $pdate ) = ( $pfile =~ /^([\d]+)_${base_ver}_([\d]{4})\.zip$/i ); # need to convert
( $pmon, $pyear ) = ( $pdate =~ /^(\d\d)(\d\d)$/ ); # need to convert
if( ($patch_nbr == 0) || ($patch_nbr == $pnum) ) {
$fcnt++;
}
}
}
我在这里转换了大部分内容..
$file_list = Get-ChildItem -force $base_dir
$file_list | foreach-object {
if($_ -match "/^([\d]+)_${base_ver}_([\d]{4})\.zip$/i"){
$pfile = $_
if($patch_nbr -eq 0 -or $pacth_nbr -eq $pnum){
$fcnt++
}
}
}
不太确定如何转换等于正则表达式的两个变量,或者是否有更好的方法将perl代码转换为powershell而不是我已有的。
答案 0 :(得分:3)
来自[mode]/pattern/[replace/][options]
的{{1}}语法不适用于PowerShell中的正则表达式。
因此,你的模式
perl
变为
/^([\d]+)_${base_ver}_([\d]{4})\.zip$/i
(^([\d]+)_${base_ver}_([\d]{4})\.zip$
是不必要的,i
默认解析为-match
(案例 - 我不敏感匹配)
要捕获数字前缀和日期,您可以使用命名捕获组(-imatch
):
(?<name>pattern)
然后,您可以从^(?<num>[\d]+)_${base_ver}_(?<date>[\d]{4})\.zip$
获取匹配:
$Matches["name"]
您还可以更改正则表达式模式以单独捕获月份和年份:
if($f -match "^(?<num>[\d]+)_${base_ver}_(?<date>[\d]{4})\.zip$"){
$pfile = $f
$pnum = $Matches["num"]
$pdate = $Matches["date"]
$pmon = -join $pdate[0..1]
$pyear = -join $pdate[2..3]
}
答案 1 :(得分:2)
我先放一个Where-Object
过滤器。这样,您就可以在后续$matches
中使用ForEach-Object
集合而不会在嵌套-match
语句中使用第二个if
。如果您还将日期模式从(\d{4})
更改为(\d{2})(\d{2})
,则可以在单个语句中指定$pnum
,$pmon
和$pyear
。您还可以简化递增$fcnt
的条件。不是检查$patch_nbr
是否等于两个值中的一个,而是检查它是否包含在两个值的数组中。
Get-ChildItem -Force $base_dir |
Where-Object { $_ -match '^(\d+)_${base_ver}_(\d{2})(\d{2})\.zip$' } |
ForEach-Object {
$pnum, $pmon, $pyear = $matches[1..3]
if (0, $pnum -contains $patch_nbr) { $fcnt++ }
}
}
当然,如果您只想计算与给定修补程序编号匹配的文件数,您可以执行以下操作:
$f = Get-ChildItem -Force $base_dir | Where-Object {
$_ -match '^(\d+)_${base_ver}_\d{4}\.zip$' -and
0, $matches[1] -contains $patch_nbr
}
$fcnt = @($f).Count