Lost
Lost

Reputation: 53

How to match a string unless it contains something?

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

Answers (3)

Ansgar Wiechers
Ansgar Wiechers

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

Kasravnd
Kasravnd

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).)*$

DEMO

Note that you need to use modifier m (multiline) for multiline string.

Upvotes: 3

Wiktor Stribiżew
Wiktor Stribiżew

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

Related Questions