• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 90
  • Last Modified:

PHP/REGEX: Where file names do not have underscore with glob

$f = glob('files/courses/{*_[0-9]*.zip}', GLOB_BRACE);

Open in new window

This matches:
x_123.zip
y_543.zip
z_789.zip

But it does not match:
x123.zip
y543.zip
z789.zip

How can I get it to match:
x123.zip
y543.zip
z789.zip

but not:
x_123.zip
y_543.zip
z_789.zip
?
0
skij
Asked:
skij
  • 3
  • 2
  • 2
  • +1
3 Solutions
 
gr8gonzoConsultantCommented:
add a ? after the _
0
 
skijAuthor Commented:
I don't want these to match!
x_123.zip
y_543.zip
z_789.zip

If there is a _ before the number then it should not match.
0
 
Dan CraciunIT ConsultantCommented:
$f = glob('files/courses/{[^_]+[0-9]*.zip}', GLOB_BRACE);

HTH,
Dan
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
gr8gonzoConsultantCommented:
{[a-zA-Z0-9]+.zip}
0
 
skijAuthor Commented:
Please look carefully at the examples I gave in my original post.

None of the ideas work with the examples provided.
0
 
gr8gonzoConsultantCommented:
Sorry - I was trying to get back a quick response earlier. I have a few more minutes now and I can tell you that glob() doesn't have a full regex engine, which will make it pretty difficult to do any sort of complex filtering in the future.

So if those are truly the filenames, then this should work:
$f = glob('files/courses/[a-z][0-9]*.zip');

But I'd recommend you set yourself up for success later on and put in a quick use of the full regex engine using preg_match to filter the results that come back:

$f = glob('files/courses/*[0-9]*.zip');
foreach($f as $fk => $fv) { if(!preg_match("/^[a-zA-Z][0-9]+.zip/",basename($fv))) { unset($f[$fk]); } }
0
 
Julian HansenCommented:
glob is actually quite a slow function - especially if you are going to iterate through the results afterwards.
Try the FileSystemIterator instead

$regex = "/^[a-zA-Z]+[0-9]+\.zip$/";
$path = 'files/courses';

$iterator = new FilesystemIterator($path, FilesystemIterator::SKIP_DOTS + FilesystemIterator::CURRENT_AS_PATHNAME + FilesystemIterator::KEY_AS_FILENAME);
$desirable = array();
foreach ($iterator as $key => $filepath) {
  if (preg_match($regex, $key)) {
    $desirable[] = $filepath;
  }
}

Open in new window

EDIT
Changed to use KEY_AS_FILENAME to remove requirement for basename - 50% faster.
0
 
Julian HansenCommented:
For interest FSI ran in approx 1/5 of the time of the glob solution.
0

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

  • 3
  • 2
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now