使用正则表达式过滤PowerShell文件名

3
我正在建立一个包含文件的列表,并将其存储在变量 $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变量中,这样我就可以捕获像上面$list变量中的test120119.txt这样具有日期时间戳的文件名。
我该如何更改我的代码来支持正则表达式?我尝试了一些不需要分割$list的select-string变体,但并没有得到好结果。我还尝试将我的-notin更改为-notmatch,但这当然根本行不通。

“-notin” 集合运算符不支持正则表达式 - 它只能进行精确的、完全匹配。这意味着您的 $Filter 需要 $_ 项与 $Filter 集合中的一个项的原始文本完全匹配。AdminOfThings 的解决方案似乎更适合您的目标。[咧嘴笑] - Lee_Dailey
1个回答

9
如果你想使用正则表达式,我认为最好全面采用正则表达式,并在你的$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() 方法来为您执行此操作,但前提是您没有故意注入正则表达式字符。
一旦您拥有了正则表达式过滤器列表,您可以使用|字符将每个项目连接到一个正则表达式或语句中。
并非所有运算符都能识别正则表达式语言。 -match-notmatch 是为数不多的可以识别正则表达式的运算符之一。 -match-notmatch 不区分大小写。 如果您想进行区分大小写匹配,则应使用运算符的-c变体,即-cmatch-cnotmatch
正则表达式项可以根据您的喜好进行调整。 为了得出精确的解决方案,还需要提供更多要求。以下是一些考虑的示例:
  • \d{0,6}匹配零到六个连续数字。122619将成功匹配,1226也将成功匹配。如果您只希望匹配0或6个数字,可以使用(\d{6})?
  • 如果您想在输入字符串的开头开始每个匹配,请使用^。因此,如果您希望正则表达式或应用于字符串的开头,则需要在每个项中包含^,或者在初始的^后面的每个项目或组项目中相应地包含()^item1 | ^item2将返回与^(item1 | item2)相同的捕获组0匹配。
  • \转义字面字符.
  • 不使用锚点字符如^$会创建很多灵活性和潜在的不想要结果。 'FakeFile' -match 'Fake' 返回true,但'MyFakeFile' -match 'Fake' 也是如此。然而,'MyFakeFile' -match 'Fake$'返回false,'MyFake' -match 'Fake$'返回true。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接