PHP:while循环-在条件中使用修改过的变量

PHP:while循环-在条件中使用修改过的变量,php,while-loop,preg-replace,Php,While Loop,Preg Replace,我在PHP中遇到了一个while循环问题,如果它在其他地方,似乎可以使用符号符号将其作为参考来解决。下面是一个例子。我正试图在basename中的文件名后面追加n。如果有1,我希望它是2,如果有2,我希望它是3,依此类推。由于某些原因,我无法在条件中更新$filename变量,因此我认为它在循环中不会被更改 $dir = 'images'; $filename = '123.jpg'; $i = 0; while (file_exists($dir.'/'.$filename)) { $

我在PHP中遇到了一个while循环问题,如果它在其他地方,似乎可以使用符号符号将其作为参考来解决。下面是一个例子。我正试图在basename中的文件名后面追加n。如果有1,我希望它是2,如果有2,我希望它是3,依此类推。由于某些原因,我无法在条件中更新$filename变量,因此我认为它在循环中不会被更改

$dir = 'images';
$filename = '123.jpg';
$i = 0;
while (file_exists($dir.'/'.$filename)) {
    $filename = preg_replace('/^(\d*?)(\.jpg)$/',"$1_".(++$i)."$2",$filename);
}
echo $filename;

我做错了什么?

看起来您的正则表达式有点不正确,如果它已经存在,您就无法捕获它

while (file_exists($dir.'/'.$filename)) {
  $filename = preg_replace('/^(\d+)(.*)(\.jpg)$/',"$1_".(++$i)."$3",$filename);
  //-------------------------------^^^^ Capture the _n if it exists
  // And stick the number in with $1 and $3 (now the .jog)
}
echo $filename;

// Current files...
123_1.jpg
123_2.jpg
123.jpg

// Outputs 123_3.jpg

看起来您的正则表达式有点不正确,如果它已经存在,您就无法捕获它

while (file_exists($dir.'/'.$filename)) {
  $filename = preg_replace('/^(\d+)(.*)(\.jpg)$/',"$1_".(++$i)."$3",$filename);
  //-------------------------------^^^^ Capture the _n if it exists
  // And stick the number in with $1 and $3 (now the .jog)
}
echo $filename;

// Current files...
123_1.jpg
123_2.jpg
123.jpg

// Outputs 123_3.jpg

如果您不想使用正则表达式,并且希望确保将所有jpg文件保存在一个目录中,则可以使用glob和一些基本的字符串操作函数,如:

$dir = 'images/';
foreach (glob($dir.'*.jpg') as $file) {
  $ext = strpos($file, '.jpg'); // get index of the extension in string
  $num = (int) substr($file, 0, $ext); // get the numeric part
  $file = $num+1 . '.jpg'; // rebuild the file name
  echo $file, PHP_EOL;
}

如果您不想使用正则表达式,并且希望确保将所有jpg文件保存在一个目录中,则可以使用glob和一些基本的字符串操作函数,如:

$dir = 'images/';
foreach (glob($dir.'*.jpg') as $file) {
  $ext = strpos($file, '.jpg'); // get index of the extension in string
  $num = (int) substr($file, 0, $ext); // get the numeric part
  $file = $num+1 . '.jpg'; // rebuild the file name
  echo $file, PHP_EOL;
}

下面是一个使用函数而不使用正则表达式的示例。这种方法适用于更广泛的环境

i、 e.任何文件扩展名都有效,并且basename中允许使用下划线或句点

如果您不需要这些东西,那么使用preg_replace更干净,请参阅Michael的答案

<?php

function nextUnusedFileName($path, $fileName){
    $index = 1;
    while (file_exists($path."/".$fileName)) 
    {
        $baseNameEndIndex = strrpos($fileName, '_'); 
        $extensionStartIndex = strrpos($fileName, '.');
        if($baseNameEndIndex <= 0){
            $baseNameEndIndex = $extensionStartIndex;
        }
        $baseName = substr($fileName, 0, $baseNameEndIndex)."_".$index; 
        $extension = substr($fileName, $extensionStartIndex+1, strlen($fileName)-$extensionStartIndex);
        $fileName = $baseName.".".$extension;
        $index++ ;
    }
    return $fileName;
}//end nextUnusedFileName


//main

$dir = "images";
$filename = "123.jpg";

$filename = nextUnusedFileName($dir, $filename);

echo $filename;
?>

下面是一个使用函数而不使用正则表达式的示例。这种方法适用于更广泛的环境

i、 e.任何文件扩展名都有效,并且basename中允许使用下划线或句点

如果您不需要这些东西,那么使用preg_replace更干净,请参阅Michael的答案

<?php

function nextUnusedFileName($path, $fileName){
    $index = 1;
    while (file_exists($path."/".$fileName)) 
    {
        $baseNameEndIndex = strrpos($fileName, '_'); 
        $extensionStartIndex = strrpos($fileName, '.');
        if($baseNameEndIndex <= 0){
            $baseNameEndIndex = $extensionStartIndex;
        }
        $baseName = substr($fileName, 0, $baseNameEndIndex)."_".$index; 
        $extension = substr($fileName, $extensionStartIndex+1, strlen($fileName)-$extensionStartIndex);
        $fileName = $baseName.".".$extension;
        $index++ ;
    }
    return $fileName;
}//end nextUnusedFileName


//main

$dir = "images";
$filename = "123.jpg";

$filename = nextUnusedFileName($dir, $filename);

echo $filename;
?>

我得出了同样的结论+1确切地说。我怎么会错过呢。非常感谢。还是有点不对劲。我用/^\d+\ud+?\.jpg$/试过了,但还没有成功。@我的测试和上面的测试完全一样。*而不是你的d+。我在自己的文件系统中进行了验证,得出了相同的结论+1确切地说。我怎么会错过呢。非常感谢。还是有点不对劲。我用/^\d+\ud+?\.jpg$/试过了,但还没有成功。@我的测试和上面的测试完全一样。*而不是你的d+。我在自己的文件系统中进行了验证。谢谢。问题是,如果已经存在具有该名称的文件,则将_n附加到basename。您的最后一行是将文件名从“123.jpg”更改为“124.jpg”,还是我误解了?啊,我明白了-我误解了您的问题。我会做一些编辑。它已经解决了,但是如果你有一个替代的解决方案,如果它不困扰你,那就继续吧:是的,我重新创建了我的答案,然后意识到它与MichaelThanks接受的答案是一样的:+1。问题是,如果已经存在具有该名称的文件,则将_n附加到basename。您的最后一行是将文件名从“123.jpg”更改为“124.jpg”,还是我误解了?啊,我明白了-我误解了您的问题。我会做一些编辑。它已经解决了,但是如果你有一个替代的解决方案,如果它不困扰你,那就继续吧:是的,我重新创建了我的答案,然后意识到它与迈克尔的公认答案是一样的:+1