By alex


2010-03-26 01:27:00 8 Comments

I want all CSV files in a directory, so I use

glob('my/dir/*.CSV')

This however doesn't find files with a lowercase CSV extension.

I could use

glob('my/dir/*.{CSV,csv}', GLOB_BRACE);

But is there a way to allow all mixed case versions? Or is this just a limitation of glob() ?

10 comments

@Lee Traynor 2019-07-13 21:34:52

Building on Alex's tip this could help generally:

function glob_files ($d, $e)
{
    $files = preg_grep ("/$e\$/i", glob ("$d/*"));
    sort ($files)
    return $files;
}

where $d is the directory and $e is the extension.

@Henry 2018-12-15 21:47:52

This code works for me to get images only and case insensitive.

imgage list:

  • image1.Jpg
  • image2.JPG
  • image3.jpg
  • image4.GIF
$imageOnly = '*.{[jJ][pP][gG],[jJ][pP][eE][gG],[pP][nN][gG],[gG][iI][fF]}';
$arr_files = (array) glob($path . $imageOnly, GLOB_BRACE);

Perhaps it looks ugly but you only have to declare the $imageOnly once and can use it where needed. You can also declare $jpgOnly etc.

I even made a function to create this pattern.

/*--------------------------------------------------------------------------
 * create case insensitive patterns for glob or simular functions
 * ['jpg','gif'] as input
 * converted to: *.{[Jj][Pp][Gg],[Gg][Ii][Ff]}
 */
function globCaseInsensitivePattern($arr_extensions = []) {
   $opbouw = '';
   $comma = '';
   foreach ($arr_extensions as $ext) {
       $opbouw .= $comma;
       $comma = ',';
       foreach (str_split($ext) as $letter) {
           $opbouw .= '[' . strtoupper($letter) . strtolower($letter) . ']';
       }
   }
   if ($opbouw) {
       return '*.{' . $opbouw . '}';
   }
   // if no pattern given show all
   return '*';
} // end function

$arr_extensions = [
        'jpg',
        'jpeg',
        'png',
        'gif',
    ];
$imageOnly = globCaseInsensitivePattern($arr_extensions);
$arr_files = (array) glob($path . $imageOnly, GLOB_BRACE);

@user3058870 2018-03-02 18:57:55

Came to this link for glob with multiple files. Although it doesn't help with OP, it may help others who end up here.

$file_type = 'csv,jpeg,gif,png,jpg';
$i = '0';
foreach(explode(",",$file_type) as $row){
    if ($i == '0') {
        $file_types = $row.','.strtoupper($row);
    } else {
        $file_types .= ','.$row.','.strtoupper($row);
    }
    $i++;
}

$files = glob($dir."*.{".$image_types."}",GLOB_BRACE);

@alex 2018-03-05 10:34:38

$i as '0'? Why?

@user3058870 2018-03-06 14:30:55

0 is the first element in the array

@alex 2018-03-06 16:07:37

I mean, you're using it as a loop index, but defining it as a string.

@user3058870 2018-03-08 00:02:53

It's called a numeric string and functions with arithmetic operators.

@Dan Bray 2017-03-04 00:58:21

To make it work with all extensions use:

$extension = 'some_extension';
glob('my/dir/*.preg_replace('/(\w)/e', "'['.strtoupper($1).strtolower($1).']'", $extension));

@cautionbug 2018-01-10 04:09:26

i can't speak for whomever down-voted you, but a couple of (hopefully helpful) points: (1) your path string is missing the closing ', and (2) the PCRE e (eval) flag is deprecated as of PHP 5.5 and removed in 7, both of which are older than this answer. Its usage is discouraged.

@alex 2018-03-05 11:33:23

preg_replace() is needlessly used. You could explode(), map(), return the case variants and then join().

@Jerry 2015-03-30 23:35:38

I heard about a function that can be used like this: Try if that works for you!

<?php
$pattern = sql_regcase("*.txt");
glob($pattern);
?>

@alex 2015-03-31 06:49:01

Interesting. Its use has been deprecated though.

@Timo Huovinen 2014-10-08 12:15:06

You can also filter out the files after selecting all of them

foreach(glob('my/dir/*') as $file){
    $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
    if(!in_array($ext, array('csv'))){
        continue;
    }
    ... do stuff ...
}

performance wise this might not be the best option if for example you have 1 million files that are not csv in the folder.

@Oli Comber 2014-02-13 09:54:09

You can write your own case insensitive glob. This is from a personal web library I write:

/** PHP has no case insensitive globbing
 * so we have to build our own.
 *
 * $base will be the initial part of the path which doesn't need case insensitive
 * globbing.
 * Suffix is similar - it will not be made insensitive
 * Make good use of $base and $suffix to keep $pat simple and fast in use.
 */
    function ciGlob($pat, $base = '', $suffix = '')
    {
        $p = $base;
        for($x=0; $x<strlen($pat); $x++)
        {
            $c = substr($pat, $x, 1);
            if( preg_match("/[^A-Za-z]/", $c) )
            {
                $p .= $c;
                continue;
            }
            $a = strtolower($c);
            $b = strtoupper($c);
            $p .= "[{$a}{$b}]";
        }
        $p .= $suffix;
        return glob($p);
    }

@intuited 2010-03-26 01:45:20

glob('my/dir/*.[cC][sS][vV]') should do it. Yeah it's kind of ugly.

@Ignacio Vazquez-Abrams 2010-03-26 01:37:22

Glob patterns support character ranges:

glob('my/dir/*.[cC][sS][vV]')

@JohnK 2012-07-31 09:14:59

But won't it also match any file that ends in ".Csv" or ".CsV"? But that's a sidepoint: what I'm looking for is a pattern that will match all image files in a case insensitive way (jpg, JPG, png, PNG, etc.).

@Ignacio Vazquez-Abrams 2012-07-31 09:43:23

@JohnK: "But is there a way to allow all mixed case versions?"

@alex 2010-03-26 01:33:04

You could do this

$files = glob('my/dir/*');

$csvFiles =  preg_grep('/\.csv$/i', $files);

@concept 2013-10-08 14:58:08

Very clean and flexible.

@Tyler V. 2014-06-12 23:52:29

Agree. It seems you can't combine GLOB_BRACE with character ranges, so I ended up using glob+preg_grep to do a case insensitive search of multiple file formats at once. Thanks for the tip!

@Jonathan 2017-02-17 10:25:39

This is the most useful solution imo.

@tjespe 2017-06-18 20:52:41

Will this be slower or take up more memory than a normal and case sensitive glob?

@alex 2017-06-19 08:22:59

@tjespe In theory slower and more memory as there is an extra iteration that filters the original array and a new array created.

Related Questions

Sponsored Content

12 Answered Questions

[SOLVED] Contains case insensitive

24 Answered Questions

[SOLVED] How to use glob() to find files recursively?

13 Answered Questions

[SOLVED] How to do case insensitive search in Vim

25 Answered Questions

[SOLVED] Case insensitive 'Contains(string)'

23 Answered Questions

[SOLVED] MongoDB: Is it possible to make a case-insensitive query?

9 Answered Questions

[SOLVED] How do I do a case-insensitive string comparison?

18 Answered Questions

[SOLVED] Test whether a glob has any matches in bash

  • 2010-05-30 03:22:46
  • Ken Bloom
  • 47051 View
  • 220 Score
  • 18 Answer
  • Tags:   bash glob

11 Answered Questions

[SOLVED] Case-insensitive search

3 Answered Questions

[SOLVED] How to make this .htaccess rule case insensitive?

Sponsored Content