PHP正则表达式忽略以双__underscore开头的文件

I have tried, but I simply can't wrap my head around regex in PHP. I need a regex that does the following:

  • ignores files that start with double __underscore. (for example __file.jpg)
  • ignores files that end with "thumb". (for example somethumb.jpg or thumb.jpg)
  • ignores all file types but gif|jpg|png|jpeg

I have the following for now, which seems to fulfill #2 and #3, but not #1:

preg_match(/(?<!thumb)\.(gif|jpg|png|jpeg)$/i, $file)

Any help much appreciated!

If I understood third point correctly it means that it should end with all these file extensions. Considering this, the following will work

1st Solution

(?!^__|.*thumb\.(gif|jpg|png|jpeg))(^.*)(?=\.(gif|jpg|png|jpeg)$)

Regex Demo

Towards an efficient solution

2nd Solution

^(?!__|.*thumb\.(?:gif|jpg|png|jpeg))(.*(?=\.(?:gif|jpg|png|jpeg)$).*$)

3rd Solution (suggested by Wiktor in comments)

^(?!__|.*thumb\.(?:gif|jpg|png|jpeg))(?=.*\.(?:gif|jpg|png|jpeg)$).*

4th Solution (suggested by Casimir in comments)

^(?!__)(?:[^.
]*\.)*+(?<!thumb\.)(?:jpe?g|png|gif)$

PHP Code

$re = "/^(?!__|.*thumb\\.(?:gif|jpg|png|jpeg))(?=.*\\.(?:gif|jpg|png|jpeg)$)(.*)/m";
$str = "__abcd.jpg
thumbabcd.gif
thumbabcdthumb.jpg
thumbs.jpg
somethumb.jpg
thumb.jpg
abcd.jpg
abcd.jps"; 

preg_match_all($re, $str, $matches);

Ideone Demo

This might be kind of an overkill, but you could come up with some subroutines for a better readability:

(?(DEFINE)
  # condition1
  (?<condition1>(?!(?:^__)))
  # condition2
  (?<condition2>(?!.*thumb))
  # allowed extensions 
  (?<ext>\.(?:gif|png|jpe?g)$)
)
^(?&condition1)(?&condition2).+(?&ext)$

See a demo on regex101.com.