我知道的最清楚的方法是进行两阶段评估(使用/e
修饰符)替换。
在下面的代码中,外部替换选择艺术家姓名,包括其边界连字符并替换它。
内层采用$1
- 艺术家姓名 - 并将非空格字符的每个子序列替换为相同的字符串,首先小写lc
字母,然后大写字母ucfirst
。
就目前而言,该程序将打印之前和之后的名称。#
从重命名行中删除以进行重命名。
use strict;
use warnings;
my @data = (
'05 - JEAN BAGUETTE - Honi soit qui mal y pense.mp3',
'07 - SIGNORE AL FORNO - Pazzi sono tutti i calciatori.mp3',
);
for my $file (@data) {
(my $new = $file) =~ s{(-[^-]+-)}{
(my $artist = $1) =~ s/(\S+)/ucfirst lc $1/eg;
$artist;
}e;
print "$file\n";
print "$new\n";
print "\n";
# rename $file, $new;
}
输出
05 - JEAN BAGUETTE - Honi soit qui mal y pense.mp3
05 - Jean Baguette - Honi soit qui mal y pense.mp3
07 - SIGNORE AL FORNO - Pazzi sono tutti i calciatori.mp3
07 - Signore Al Forno - Pazzi sono tutti i calciatori.mp3
更新
您可能喜欢的另一种方法是在连字符上拆分文件名,编辑第二部分并将它们重新连接在一起。
上面的主循环变成
for my $file (@data) {
my @file = split /-/, $file;
$file[1] =~ s/(\S+)/ucfirst lc $1/eg;
my $new = join '-', @file;
print "$file\n";
print "$new\n";
print "\n";
# rename $file, $new;
}
功能和输出不变。
更新 2
我刚刚尝试使用 /-.*?-/ 然后使用 substr($_, $-[0], $+[0]) 作为 =~ s/// 的左值,但遗憾的是它没有用
这似乎是一个很好的想法,我不得不尝试一下。
您的调用substr
是错误的,因为$-[0]
和$+[0]
是字符串的偏移量。第三个参数substr
必须是字符串长度,所以你需要写substr($_, $-[0], $+[0] - $-[0])
此代码工作正常,并再次产生与以前相同的结果
for my $file (@data) {
next unless $file =~ /-[^-]+-/;
my $new = $file;
substr($new, $-[0], $+[0]-$-[0]) =~ s/(\S+)/ucfirst lc $1/eg;
print "$file\n";
print "$new\n";
print "\n";
# rename $file, $new;
}