|
Posted by Colin Fine on 10/02/06 22:35
Colin Fine wrote:
> Mr Phuzz wrote:
>> Hello,
>>
>> I'm pretty new to PHP and am wrestling with regexp's right now. I am
>> trying to figure something out with no luck. Hopefully someone can
>> help.
>>
>> I am trying to filter out file names. I want to write a regexp that
>> matches all image file names, such as ".jpg", ".bmp", ".png", etc...
>> but not file names that end with "_thumb.***" (where *** is the
>> extension of the file name... which can be 3 or 4 chars long). So...
>>
>> somepic.jpg <--- should match
>> somepic_thumb.jpg <--- should not match
>> anotherpic.png <--- should match
>> this_thumb.is_broken.jpg <--- should match
>>
>> Currently, I do this using two regexps. First, I compare to determine
>> if the file is an image by looking at the end and seeing if it's .jpg,
>> .png, etc. If that passes, I compare again to see if it contains
>> "_thumb.***" at the end (allowing for 3 or 4 chars, such as jpg or
>> jpeg), as such:
>>
>> if(preg_match("/(.jpg|.jpeg|.gif|.png|.bmp)$/i", $filename)){
>> if(!preg_match("/(_thumb.).{3,4}$/i", $filename)){
>> $files[]=$filename;
>> print("$filename<br>");
>> }
>> }
>>
>> How can I, if possible, combine these into one regexp?
>>
>> Thanks for your time,
>> Mr Phuzz
>>
>
> You can do it by a negative lookbehind assertion:
>
> '/(?<!_thumb)\.(jpg|jpeg|gif|png|bmp)$/'
>
> finds an instance of .jpg etc that is not preceded by _thumb
>
> (You want to escape the . anyway, as otherwise it will match any
> character.)
>
> Colin
But on second thought, many people would prefer two matches (even if it
is a tiny bit less efficient) rather than using such an obscure pattern.
You could then also capture the file type and use it in the second pattern:
if(preg_match("/\.(jpg|jpeg|gif|png|bmp)$/i", $filename, $match) &&
!preg_match("/_thumb\.$match[1]$/i", $filename)){
Colin
[Back to original message]
|