在字符串替换中我们如何使用'/ r'修饰符

时间:2018-03-12 10:27:57

标签: perl

我需要在字符串中增加一个数值:

my $str = "tool_v01.zip";

(my $newstr = $str)  =~ s/\_v(\d+)\.zip$/ ($1++);/eri;
#(my $newstr = $str) =~ s/\_v(\d+)\.zip$/ ($1+1);/eri;
#(my $newstr = $str) =~ s/\_v(\d+)\.zip$/ $1=~s{(\d+)}{$1+1}/r; /eri;

print $newstr;

预期输出为tool_v02.zip

注意:版本号01可能包含任意数量的前导

2 个答案:

答案 0 :(得分:3)

我不认为这个问题与/r修饰符有什么关系,而是如何正确格式化输出。为此,我建议sprintf

my $newstr = $str =~ s{ _v (\d+) \.zip$ }
    { sprintf("_v%0*d.zip", length($1), $1+1 ) }xeri;

或者,只用零宽度Lookaround Assertions替换数字:

my $newstr = $str =~ s{ (?<= _v ) (\d+) (?= \.zip$ ) }
    { sprintf("%0*d", length($1), $1+1 ) }xeri;

注意:使用其中任何一种解决方案,tool_v99.zip之类的内容都会更改为tool_v100.zip,因为新的序列号不能用两个字符表示。如果那不是您想要的,那么您需要指定您需要的替代行为。

答案 1 :(得分:0)

您丢失的位是sprintf,其工作方式与printf相同,只是将格式化字符串输出到stdout或文件句柄,它将其返回为一个字符串。例如:

sprintf("%02d",3)

生成字符串03

将它放入你的正则表达式你可以做到这一点。不是使用/r,而是可以使用零宽度前瞻((?=...))来匹配文件后缀,只需将匹配的数字替换为新值

s/(\d+)(?=.zip$)/sprintf("%02d",$1+1)/ei