如何用更简洁的PowerShell代码匹配文件名中的多个关键词
简洁实现PowerShell文件名多关键词部分匹配
问题背景
需要用最简洁的代码,判断脚本文件名(随机长名称,但必含指定关键词)是否包含某组关键词中的任意一个。原尝试的多值-match写法始终进入Else分支,用-or拼接多个-match可行但代码冗余,-in无法实现部分匹配,求更简洁的实现方式。
失效代码示例
$ScriptFileName = (Get-Item $PSCommandPath).Basename If (($ScriptFileName -match "Report", "Global", "Monthly")) { Write-Output "All days" } ElseIF (($ScriptFileName -match "Day", "Hour", "Present")) { Write-Output "Today" } Else { Write-Output "Other file name"} Pause
可行但繁琐的代码示例
$ScriptFileName = (Get-Item $PSCommandPath).Basename If (($ScriptFileName -match "Report") -or ($ScriptFileName -match "Global") -or ($ScriptFileName -match "Monthly")) { Write-Output "All days" } ElseIF (($ScriptFileName -match "Day") -or ($ScriptFileName -match "Hour") -or ($ScriptFileName -match "Present")) { Write-Output "Today" } Else { Write-Output "Other file name"} Pause
最优解决方案
利用PowerShell-match对正则表达式的支持,将多组关键词用|拼接成正则分支表达式,一行即可完成多关键词的部分匹配,代码简洁且逻辑清晰。
优化后代码
$ScriptFileName = (Get-Item $PSCommandPath).Basename if ($ScriptFileName -match 'Report|Global|Monthly') { Write-Output "All days" } elseif ($ScriptFileName -match 'Day|Hour|Present') { Write-Output "Today" } else { Write-Output "Other file name" } Pause
原写法失效原因
当给-match传入字符串数组时,它的行为会变成数组过滤:返回数组中能匹配目标字符串的元素,而非布尔值。原代码的逻辑是用文件名匹配数组中的关键词,但实际执行时是用数组元素匹配文件名,逻辑倒置导致判断失效,最终总是进入Else分支。
特殊场景补充
如果关键词包含正则特殊字符(如., *, ?等),需要先转义避免语法干扰,示例:
$allDaysKeywords = 'Report.v2', 'Global*Data', 'Monthly' # 转义关键词并拼接成正则表达式 $allDaysPattern = ($allDaysKeywords | ForEach-Object { [regex]::Escape($_) }) -join '|' $todayKeywords = 'Day.Log', 'Hour?ly', 'Present' $todayPattern = ($todayKeywords | ForEach-Object { [regex]::Escape($_) }) -join '|' $ScriptFileName = (Get-Item $PSCommandPath).Basename if ($ScriptFileName -match $allDaysPattern) { Write-Output "All days" } elseif ($ScriptFileName -match $todayPattern) { Write-Output "Today" } else { Write-Output "Other file name" }
内容的提问来源于stack exchange,提问作者MikeZetPL
相关产品推荐
相关产品推荐

