可以使 PHP 的 glob() 以不区分大小写的方式查找文件吗?
Posted
技术标签:
【中文标题】可以使 PHP 的 glob() 以不区分大小写的方式查找文件吗?【英文标题】:Can PHP's glob() be made to find files in a case insensitive manner? 【发布时间】:2011-02-01 00:18:49 【问题描述】:我想要一个目录中的所有 CSV 文件,所以我使用
glob('my/dir/*.CSV')
但是,这不会找到具有小写 CSV 扩展名的文件。
我可以使用
glob('my/dir/*.CSV,csv', GLOB_BRACE);
但是有没有办法允许所有混合大小写版本?还是这只是glob()
的限制?
【问题讨论】:
请注意,glob()
在 Windows 中实际上是不区分大小写的(可能还有其他不区分大小写的文件系统)。
那不是真的。 glob("*.CSV")
只会查找大写文件,而glob("*.csv")
只会查找小写文件。 --- 在 windows7 中使用 php 5.3.8 测试
【参考方案1】:
你可以这样做
$files = glob('my/dir/*');
$csvFiles = preg_grep('/\.csv$/i', $files);
【讨论】:
非常干净和灵活。 同意。看来您不能将 GLOB_BRACE 与字符范围结合起来,所以我最终使用 glob+preg_grep 一次对多种文件格式进行不区分大小写的搜索。感谢您的提示! 这是 imo 最有用的解决方案。 这会比普通且区分大小写的glob
更慢或占用更多内存吗?
@tjespe 理论上更慢且内存更多,因为有一个额外的迭代来过滤原始数组和创建的新数组。【参考方案2】:
全局模式支持字符范围:
glob('my/dir/*.[cC][sS][vV]')
【讨论】:
但它不会也匹配任何以“.Csv”或“.CsV”结尾的文件吗?但这是一个支点:我正在寻找的是一种模式,它将以不区分大小写的方式(jpg、JPG、png、PNG 等)匹配所有图像文件。 @JohnK:“但是有没有办法允许所有混合大小写的版本?”【参考方案3】:glob('my/dir/*.[cC][sS][vV]')
应该这样做。是的,有点丑。
【讨论】:
【参考方案4】:您可以编写自己的不区分大小写的 glob。这是来自我写的一个个人网络图书馆:
/** 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);
【讨论】:
【参考方案5】:你也可以全选后过滤掉文件
foreach(glob('my/dir/*') as $file)
$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
if(!in_array($ext, array('csv')))
continue;
... do stuff ...
就性能而言,如果文件夹中有 100 万个非 csv 文件,这可能不是最佳选择。
【讨论】:
【参考方案6】:我听说有一个函数可以这样使用: 试试这是否适合你!
<?php
$pattern = sql_regcase("*.txt");
glob($pattern);
?>
【讨论】:
有趣。但它的使用已被弃用。【参考方案7】:要使其适用于所有扩展,请使用:
$extension = 'some_extension';
glob('my/dir/*.preg_replace('/(\w)/e', "'['.strtoupper($1).strtolower($1).']'", $extension));
【讨论】:
我不能代表投票给你的人,但有几点(希望有帮助):(1)你的路径字符串缺少结束'
,以及(2)PCRE e
(eval) 标志自 PHP 5.5 起已弃用,并在 7 中删除,两者都比这个答案更早。不鼓励使用它。
preg_replace()
是不必要的使用。您可以explode()
、map()
,返回大小写变体,然后返回join()
。【参考方案8】:
来到此链接以获取包含多个文件的 glob。虽然它对 OP 没有帮助,但它可能会帮助到这里的其他人。
$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);
【讨论】:
$i
为'0'
?为什么?
0 是数组的第一个元素
我的意思是,您将它用作循环索引,但将其定义为字符串。
它被称为数字字符串和带有算术运算符的函数。【参考方案9】:
此代码仅适用于获取图像且不区分大小写。
图片列表:
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);
也许它看起来很丑,但你只需要声明一次 $imageOnly 并且可以在需要的地方使用它。您还可以声明 $jpgOnly 等。
我什至做了一个函数来创建这个模式。
/*--------------------------------------------------------------------------
* 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);
【讨论】:
【参考方案10】:根据 Alex 的提示,这通常会有所帮助:
function glob_files ($d, $e)
$files = preg_grep ("/$e\$/i", glob ("$d/*"));
sort ($files)
return $files;
其中$d
是目录,$e
是扩展名。
【讨论】:
以上是关于可以使 PHP 的 glob() 以不区分大小写的方式查找文件吗?的主要内容,如果未能解决你的问题,请参考以下文章