首页 > 解决方案 > powershell 使用正则表达式过滤文件名

问题描述

我正在构建要放入 $list 变量的文件列表。

然后我想根据 $filter 变量过滤列表。当前的解决方案有效,但不适用于正则表达式。

$filter = @("test.txt","Fake","AnotherFile\d{1..6}")

######### HTML TESTS #############
[string]$list = @"
FakeFile.txt
test120119.txt
AnotherFile120119.txt
LastFile.txt
"@

[array]$files = $list -split '\r?\n'
$files = $files | Where-Object {$_} | Where {$_ -notin $filter} # filter out empty items from the array...

$files

我的想法是将正则表达式模式放在 $filter 变量中,这样我就可以捕获其中包含日期戳的文件名,例如test120119.txt上面的 $list 变量。

如何更改我的代码以允许使用正则表达式?我在不拆分 $list 的情况下尝试了一些 select-string 变体,但没有成功。我也尝试将我的更改-notin为 -notmatch 但这当然根本不起作用。

标签: powershell

解决方案


如果您想使用正则表达式,我认为使用您的$filter数组完全提交正则表达式会更容易。

$filter = "^test\d{0,6}\.txt","^Fake","^AnotherFile\d{0,6}\.txt" -join '|'

$list = @"
FakeFile.txt
test120119.txt
AnotherFile120119.txt
LastFile.txt
"@

$files = $list -split '\r?\n'
$files | Where {$_ -notmatch $filter}

要记住的是,如果您希望按字面意思对待特殊的正则表达式字符,请记住转义它们。您可以使用该[regex]::Escape()方法为您执行此操作,但如果您已经故意注入正则表达式字符,则不能。

获得正则表达式过滤器列表后,您可以or使用该|字符将每个项目与正则表达式连接起来。

并非所有运算符都能识别正则表达式语言。-match并且-notmatch是少数这样做的人之一。-match并且-notmatch不区分大小写。如果要匹配大小写,则应使用-c运算符的变体,即-cmatchand -cnotmatch

正则表达式项目可以根据您的喜好进行调整。需要提出更多要求才能提出准确的解决方案。以下是一些需要考虑的示例:

  • \d{0,6}匹配 0 到 6 个连续数字。122619将成功匹配,但1226. 如果您只想匹配 0 或 6 位数字,则可以使用(\d{6})?.
  • ^如果要在输入字符串的开头开始每个匹配,则应使用。因此,如果您希望正则表达式or从字符串的开头应用,您需要在每个项目或组项目中包含相应^的初始值。将返回与 相同的捕获组 0 匹配。^()^item1|^item2^(item1|item2)
  • \转义文字.字符。
  • 不使用锚字符,这样^$产生很大的灵活性和可能不需要的结果。'FakeFile' -match 'Fake'返回 true 但也是如此'MyFakeFile' -match 'Fake'。但是,'MyFakeFile' -match 'Fake$'返回 false 并'MyFake' -match 'Fake$'返回 true。

推荐阅读