RegEx and exclusion

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Mr Phuzz

    #1

    RegEx and exclusion

    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.j pg <--- should not match
    anotherpic.png <--- should match
    this_thumb.is_b roken.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|.gi f|.png|.bmp)$/i", $filename)){
    if(!preg_match( "/(_thumb.).{3,4} $/i", $filename)){
    $files[]=$filename;
    print("$filenam e<br>");
    }
    }

    How can I, if possible, combine these into one regexp?

    Thanks for your time,
    Mr Phuzz

  • Colin Fine

    #2
    Re: RegEx and exclusion

    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.j pg <--- should not match
    anotherpic.png <--- should match
    this_thumb.is_b roken.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|.gi f|.png|.bmp)$/i", $filename)){
    if(!preg_match( "/(_thumb.).{3,4} $/i", $filename)){
    $files[]=$filename;
    print("$filenam e<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)\.(j pg|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

    Comment

    • Colin Fine

      #3
      Re: RegEx and exclusion

      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.p ng <--- 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|.gi f|.png|.bmp)$/i", $filename)){
      > if(!preg_match( "/(_thumb.).{3,4} $/i", $filename)){
      > $files[]=$filename;
      > print("$filenam e<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)\.(j pg|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

      Comment

      Working...