我有一堆像这样命名的文件......
full-file(1).jpg
full-file(10).jpg
full-file(11).jpg
full-file(12).jpg
full-file(2).jpg
etc...
我正在尝试找出使用PHP重命名所有这些文件的最有效方法,以便它们像这样重命名...
full-file0001.jpg
full-file0010.jpg
full-file0011.jpg
full-file0012.jpg
full-file0002.jpg
我已经阅读了文件夹中的所有文件并循环浏览它们,但不确定删除括号的最佳方法,并将数字4位数设为前导0。
$image_files = get_files($thumbpath);
foreach($image_files as $index=>$file) {
echo $file;
}
答案 0 :(得分:4)
使用正则表达式获取数字,然后使用sprintf()
对其进行零填充:
$image_files = get_files($thumbpath);
foreach($image_files as $index=>$file) {
// Capture \d+ into $matches[1]
preg_match('/\((\d+)\)/', $file, $matches);
// Pad it with %04d in sprintf()
$newfile = sprintf("full-file%04d.jpg", $matches[1]);
}
示例:
php > $file = 'full-file(12).jpg';
php > preg_match('/\((\d+)\)/', $file, $matches);
php > $newfile = sprintf("full-file%04d.jpg", $matches[1]);
php > echo $newfile;
// full-file0012.jpg
为了取悦downvoter,我只能假设想要更灵活的文件名,扩展正则表达式:
$image_files = get_files($thumbpath);
foreach($image_files as $index=>$file) {
preg_match('/([^(]+)\((\d+)\)(.+)/', $file, $matches);
$newfile = sprintf("%s%04d%s", $matches[1], $matches[2], $matches[3]);
// And rename the file
if (!rename($file, $newfile)) {
echo "Could not rename $file.\n";
}
else echo "Successfully renamed $file to $newfile\n";
}
模式首先匹配,第一个(
与([^(]+)
匹配,后跟(\d+)
的数字,以及(.*)
剩余的所有内容。
答案 1 :(得分:2)
您可以混合使用REGEXP(删除括号)和字符串填充(强制四位数字)。
注意我使用替换回调在一个地方执行两个操作。
$files = array(
'full-file(1).jpg',
'full-file(10).jpg',
'full-file(11).jpg',
'full-file(12).jpg',
'full-file(2).jpg'
);
function pr_callback($match) {
return str_pad($match[1], 4, '0', STR_PAD_LEFT);
}
foreach($files as $file)
echo preg_replace_callback('/\((\d+)\)/', pr_callback, $file).'<br />';
输出:
全file0001.jpg
全file0010.jpg
全file0011.jpg
全file0012.jpg
全file0002.jpg
答案 2 :(得分:2)
我还没有看到有人推荐sscanf()
。
<?php
$files = array(
"full-file(1).jpg",
"full-file(10).jpg",
"full-file(11).jpg",
"full-file(12).jpg",
"full-file(2).jpg",
);
foreach ($files as $file) {
$n = sscanf($file, "full-file(%d).jpg");
printf("full-file%04d.jpg\n", $n[0]);
}
返回:
full-file0001.jpg
full-file0010.jpg
full-file0011.jpg
full-file0012.jpg
full-file0002.jpg
这只适用于“full-file”是文件的实际名称的情况。 sscanf()不是一个正则表达式解析器,它只是使用printf() - 样式格式字符串提取数据......虽然它确实做了比http://php.net/sscanf中记录的更高级的格式识别。如果需要处理其他文件名,可以扩展格式字符串:
<?php
$files = array(
"this-file(1).jpg",
"full-file(10).jpg",
"foo(11).jpg",
"blarg(12).jpg",
"full-file(2).jpg",
);
foreach ($files as $file) {
$n = sscanf($file, "%[a-z-](%d).jpg");
printf("%s%04d.jpg\n", $n[0], $n[1]);
}
返回:
this-file0001.jpg
full-file0010.jpg
foo0011.jpg
blarg0012.jpg
full-file0002.jpg
答案 3 :(得分:1)
您需要str-pad()。很快就会有样品......
编辑1 :使用str_pad
和preg_replace_callback
的解决方案
OBS :仅在php5.3 +中使用匿名函数。
foreach ($image_files as $file)
{
$o = preg_replace_callback(
"|\((\d+)\)|", function($matches)
{
$r = str_pad($matches[1], 4, '0', STR_PAD_LEFT);
return $r;
}
, $file);
echo $o . "\n";
}
答案 4 :(得分:1)
假设您的文件实际上并未被称为完整文件(0000)。 jpg :
<?php
$arr = array('full-file(1).jpg',
'full-file(10).jpg',
'full-file(11).png',
'full-file(12).jpg',
'full-file(2).gif',
'abc(12345).jpg',
'def(99).jpg',
'xzy-file(100).jpg');
function format_filename($matches){
return $matches[1].sprintf("%04d",$matches[3]).'.'.$matches[5];
}
function process_array(&$value){
$value = preg_replace_callback('/^(.*?)(\()(\d+)(\)).(jpg|png|gif)/','format_filename',$value);
}
array_walk($arr,'process_array');
print_r($arr);
/*
Array
(
[0] => full-file0001.jpg
[1] => full-file0010.jpg
[2] => full-file0011.png
[3] => full-file0012.jpg
[4] => full-file0002.gif
[5] => abc12345.jpg
[6] => def0099.jpg
[7] => xzy-file0100.jpg
)
*/
?>
答案 5 :(得分:1)
使用代码:
preg_match('/^(.*?)\((\d+)\)(.*)$/', $name, $m);
$name = sprintf("%s%04d%s", $m[1], $m[2], $m[3]);
查看并测试here。