Reputation: 53
I have a PowerShell script that will get a list of all files within a folder and then (based on regex matches within a Switch
statement) will move each file to a specified folder (depending on the regex match).
I'm having an issue with a particular list. A group of files (PDF files named after their part number) that begin with "40" get moved to a specified folder.
The regex itself for just THAT is easy enough for me, the problem I am having is that, IF the file contains _ol
OR _ol_
then it cannot be a match.
For example, the file names below should all match:
401234567.pdf
401234567a.pdf
401234567_a.pdf
401234567a_something.pdf
Those below should NOT match:
401234567_ol.pdf
401234567_ol_something.pdf
Using a ^(?i)40\w+[^_ol].pdf$
regex is the closest it seems I can get.
It will negate the 401234567_ol.pdf
as being a match; however, it accepts the 401234567_ol_something.pdf
. Does anybody know how I can negate that as being a match as well?
Upvotes: 5
Views: 910
Reputation: 200303
Simply use the -notmatch
operator with a pattern that matches what you want to exclude:
Get-ChildItem 'C:\source' -Filter '*.pdf' |
? { $_.BaseName -notmatch '_ol(_|$)' } |
Move-Item -Destination 'C:\destination'
or the -notlike
operator (for better performance):
Get-ChildItem 'C:\source' -Filter '*.pdf' |
? { $_.BaseName -notlike '*_ol' -and $_.BaseName -notlike '*_ol_*' } |
Move-Item -Destination 'C:\destination'
Upvotes: 0
Reputation: 107297
You can use a negative look ahead in your regex. The following regex will match any string that doesn't contains _ol
:
^((?!_ol).)*$
Note that you need to use modifier m
(multiline) for multiline string.
Upvotes: 3
Reputation: 626926
Use a negative look-ahead:
^(?i)(?!.*_ol)40\w+\.pdf$
See demo
The look-ahead (?!.*_ol)
in the very beginning of the pattern check if later in the string we do not have _ol
. If it is present, we have no match. Dot must be escaped to match a literal dot.
Upvotes: 2