简体   繁体   English

PHP-如何在点扩展名前的括号内增加文件名ID?

[英]PHP - How to increment a filename id within braces before the dot extension?

I have a file that will get modify from time to time and I need to track the file name each time there are new changes to the file. 我有一个文件,该文件会不时地进行修改,并且每次文件有新更改时都需要跟踪文件名。 I expect to a sequence of file names eventually, for example: first-filename-1701.txt, 2nd-filename-1701(1).txt, 3rd-filename-1701(2).txt and etc.. From the results of my code below, it is producing the file names as: first-filename-1701.txt, 2nd-filename-1701(1).txt, 3rd-filename-1702(2).txt, 4th-filename-1703(3).txt and so forth. 我希望最终得到一个文件名序列,例如:first-filename-1701.txt,2nd-filename-1701(1).txt,3rd-filename-1701(2).txt等。我在下面的代码中生成的文件名为:first-filename-1701.txt,2nd-filename-1701(1).txt,3rd-filename-1702(2).txt,4th-filename-1703(3) .txt等。 Can someone kindly points out what I am doing wrong? 有人可以指出我做错了什么吗? Regexp is not my every day thing. 正则表达式不是我每天的事情。 Thanks. 谢谢。

$name = 'new-foo-bar-1701(1).txt';

$re1='.*?';         # Non-greedy match on filler
$re2='\(([\d]+)\)'; # Round Braces 1

// set new filename
$_name = "";

// check if true
if($c=preg_match_all("/".$re1.$re2."/is", $name, $matches))
{
    $rbraces  = $matches[1][0] + 1;
    $_name .= preg_replace("/".$matches[1][0]."/", $rbraces, $name); 
}
else
{
    $_name .=$name; 
}

print $_name; // new-foo-bar-1702(2).txt

You do not need to find matches to replace them later, that leads to over-replacement. 您无需查找匹配项即可在以后替换它们,从而避免了替换。 You should replace "on the fly" using a preg_replace_callback that will replace exactly what is being matched (or captured). 您应该使用preg_replace_callback替换“即时”,它将完全替换匹配(或捕获)的内容。

$name = 'new-foo-bar-1701(1).txt';

$re1='.*';          # Greedy match on filler
$re2='\((\d+)\)';   # Round Braces 1

// set new filename
$_name = "";

$_name .= preg_replace_callback("/(".$re1. ")".$re2."/", function($m){
    return $m[1] . "(" . ($m[2] + 1) . ")";
}, $name); 

print $_name;

See the IDEONE demo IDEONE演示

Note that since you plan to replace the numbers at the end of the string, greedy dot matching "filler is preferred. 请注意,由于您计划替换字符串末尾的数字,因此, 贪婪的点匹配 “填充符是首选。

I don't think there is much to change in your code except this line to 我认为除了这行代码外,您的代码没有太多更改

$_name .= preg_replace("/\(".$matches[1][0]."\)/", "(".$rbraces.")", $name); 

Ideone Demo Ideone演示

Explanation 说明

\\d+ is matched to 1 , but there is 1 already present twice in your string. \\d+匹配到1 ,但有1已经出现两次在您的字符串。 So it is replaced to 2702(2) . 因此将其替换为2702(2)

In order to match 1 specifically from () , you need to put that in your regex as denoted above. 为了从()专门匹配1 ,您需要如上所述将其放入正则表达式中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM