Question

I have a regex that looks if the file extension of a file is not one of the given extensions. Is there a way I can write this without having to put the . in front of every extension?

^.*(?<!\.php|\.html|\.xml|\.js|\.css|\.bmp|\.ico|\.jpg|\.jpeg|\.png|\.gif|\.rss)$
Was it helpful?

Solution

Yes, you can make use of a non-capture group:

^.*(?<!\.(?:php|html|xml|js|css|bmp|ico|jpg|jpeg|png|gif|rss)$)$

Though it's good too to use some character classes, maybe something like that:

^.*(?<!\.(?:(?:ht|x)ml|j(?:pg|s|peg)|p(?:hp|ng)|[rc]ss|bmp|ico|gif)$)$

This reduces the processing time. Though these are not exactly working because lookbehinds have to be fixed width in PHP, as such, I would advise using a negative lookahead as below:

^(?!.*\.(?:(?:ht|x)ml|j(?:peg|s|pg)|p(?:hp|ng)|[rc]ss|bmp|ico|gif)$).*$

Initial regex takes 120 steps to match, but only 35 steps with the changes applied in the last regex.

If you want to match extensions such as .phpx however, you can use this:

^(?!.*\.(?:(?:ht|x)ml|j(?:peg|s|pg)|p(?:hp|ng)|[rc]ss|bmp|ico|gif)).*$

OTHER TIPS

Yes you can use:

^.*(?<!\.(?:php|html|xml|js|css|bmp|ico|jpe?g|png|gif|.rss)$)$

Move dot outside the group since it is common to all extension and jpg|jpeg can b written as jpe?g

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top