Reputation: 905
I've seen other posts on SO for RegEx matches excluding strings (using negative look ahead / look behind) but i'm still having a hard time getting it to work. Was hoping someone could help.
I have a RegEx
\.(gif|jpg|png)$
Which i use to match any filenames ending in (gif/jpg/png)
However i want to use an exclusion list so that certain file names will not be matched.
eg
Thanks very much!
Upvotes: 1
Views: 10019
Reputation: 795
If the number of exclusions is low, you can use multiple negative look-behinds like this:
(?<!\/foo)(?<!\/bar)(?<!www\.site\.com\/foobar)\.(gif|jpg|png)$
The '/' before foo and bar makes sure the full name matches foo or bar, it doesn't only end in it. If it is possible that there is no '/' before the filename, you need to adjust this part.
One drawback of look-behinds is that you can only use a defined length, so no *
, +
or {1,5}
is allowed. You have to specify every exception by itself.
Note that look-arounds don't change the 'position' in the string from which it is looked at, which is why you can concatenate them like that.
Upvotes: 2
Reputation: 460
I've found that trying to read my code 6 weeks later means it's almost always better to apply filters like that separately from the regular expression. If you'll pardon a little perl:
# Apply original png/gif/jpg filter to get list of files
my @files = qw/
asdf.jpg
bar.png
fdsa.png
foo.gif
foo.jpg
/;
# Filter files to only those that don't look like ^<forbidden>\.
@files = grep {
$_ !~ /^(foo|bar)\./
} @files;
This is notably also how people tend to string shell commands together.
Upvotes: 1