• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 112
  • 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
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

 
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

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