在将字符串中的whitespaces
与正则表达式匹配后,我正在尝试替换它。
my $string = "watch download Buffy the Vampire Slayer Season 1 Episode 1 Gorillavid";
if ($string =~ m!(Seasonsd+sEpisodesd+)!){
$1 =~ s!s+!!g;
say $1;
}
现在,当我运行上面的代码时,我得到了Modification of a read-only value attempted
。现在,如果我将$1
的值存储在一个变量中,然后尝试对该变量执行替换,那么它可以正常工作。
那么,有没有什么方法可以在不创建新的临时变量的情况下就地执行替换呢。
PS:有人能告诉我如何把上面的代码写成一行吗?因为我不能:)
不要乱用特殊变量,只需捕获所需的数据,同时自己进行构建输出。
$string = "watch download Buffy the Vampire Slayer Season 1 Episode 1 Gorillavid";
if ($string =~ m!Seasons(d+)sEpisodes(d+)!){
say("Season$1Episode$2");
}
看起来您想要在原始字符串中将Season 1 Episode 1
压缩为Season1Episode1
这可以方便地使用@-
和@+
以及对substr
的调用作为左值来完成
这个程序展示了的想法
use strict;
use warnings;
my $string = "watch download Buffy the Vampire Slayer Season 1 Episode 1 Gorillavid";
if ($string =~ /Seasons+d+s+Episodes+d+/ ) {
substr($string, $-[0], $+[0] - $-[0]) =~ s/s+//g;
print $string;
}
输出
watch download Buffy the Vampire Slayer Season1Episode1 Gorillavid
你没有说为什么你想在一行中写这篇文章,但如果你必须这样做,那么这将为你做
perl -pe '/Seasons*d+s*Episodes*d+/ and substr($_, $-[0], $+[0] - $-[0]) =~ s/s+//g' myfile
如果使用后脚本for
循环创建$_
的本地实例,则可以使用print(使用逗号)将替换链接起来,以实现匹配的预打印处理。
请注意,使用全局/g
选项时不需要使用括号。还要注意,这会使if语句变得多余,因为任何不匹配都会向for
循环返回一个空列表。
perl -nlwe 's/s+//g, print for /Seasons+d+s+Episodes+d+/g;' yourfile.txt
在您的脚本中,它看起来是这样的。请注意,if语句已替换为for循环。
for ( $string =~ /Seasons+d+s+Episodes+d+/g ) {
s/s+//g; # implies $_ =~ s/s+//g
say; # implies say $_
}
这主要是为了演示一个衬垫。您可以插入一个词法变量,而不是使用$_
,例如for my $match ( ... )
,如果您希望增加可读性的话。
$string =~ s{(?<=Season)s*(d+)s*(Episode)s*(d+)}{$1$3$2};
你可以试试这个:
perl -pi -e 'if($_=~/Seasonsd+sEpisodesd/){s/s+//g;}' file
测试如下:
XXX> cat temp
watch download Buffy the Vampire Slayer Season 1 Episode 1 Gorillavid
XXX> perl -pi -e 'if($_=~/Seasonsd+sEpisodesd/){s/s+//g;}' temp
XXX> cat temp
watchdownloadBuffytheVampireSlayerSeason1Episode1GorillavidXXX>