我尝试在将字符串与正则表达式匹配后替换字符串中的whitespaces
。
my $string = "watch download Buffy the Vampire Slayer Season 1 Episode 1 Gorillavid";
if ($string =~ m!(Season\s\d+\sEpisode\s\d+)!){
$1 =~ s!\s+!!g;
say $1;
}
现在当我运行上面的代码时,我得到Modification of a read-only value attempted
。现在,如果我将$1
的值存储在变量中,而不是尝试对该变量执行替换,那么它可以正常工作。
那么,有没有办法在不创建新的临时变量的情况下执行替换。
PS:有人可以告诉我如何将上述代码编写为单行代码,因为我无法:)
答案 0 :(得分:6)
不要乱用特殊变量,只需捕获所需的数据,同时自行构建输出。
$string = "watch download Buffy the Vampire Slayer Season 1 Episode 1 Gorillavid";
if ($string =~ m!Season\s(\d+)\sEpisode\s(\d+)!){
say("Season$1Episode$2");
}
答案 1 :(得分:4)
您希望在原始字符串
中将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 =~ /Season\s+\d+\s+Episode\s+\d+/ ) {
substr($string, $-[0], $+[0] - $-[0]) =~ s/\s+//g;
print $string;
}
<强>输出强>
watch download Buffy the Vampire Slayer Season1Episode1 Gorillavid
你没有说你为什么要在一行中写这个,但是如果你必须这样就可以为你做这个
perl -pe '/Season\s*\d+\s*Episode\s*\d+/ and substr($_, $-[0], $+[0] - $-[0]) =~ s/\s+//g' myfile
答案 2 :(得分:2)
如果使用后脚本for
循环来创建$_
的本地实例,则可以使用print(使用逗号)链接替换以实现预打印处理比赛。
请注意,使用全局/g
选项时不需要括号。另请注意,这会使if语句变得多余,因为任何不匹配都会将空列表返回到for
循环。
perl -nlwe 's/\s+//g, print for /Season\s+\d+\s+Episode\s+\d+/g;' yourfile.txt
在您的脚本中,它看起来像这样。请注意,if语句将替换为for循环。
for ( $string =~ /Season\s+\d+\s+Episode\s+\d+/g ) {
s/\s+//g; # implies $_ =~ s/\s+//g
say; # implies say $_
}
这主要是为了演示单线。您可以插入词法变量,而不是使用$_
,例如for my $match ( ... )
如果您想提高可读性。
答案 3 :(得分:1)
$string =~ s{(?<=Season)\s*(\d+)\s*(Episode)\s*(\d+)}{$1$3$2};
答案 4 :(得分:-1)
你可以试试这个:
perl -pi -e 'if($_=~/Season\s\d+\sEpisode\s\d/){s/\s+//g;}' file
测试如下:
XXX> cat temp
watch download Buffy the Vampire Slayer Season 1 Episode 1 Gorillavid
XXX> perl -pi -e 'if($_=~/Season\s\d+\sEpisode\s\d/){s/\s+//g;}' temp
XXX> cat temp
watchdownloadBuffytheVampireSlayerSeason1Episode1GorillavidXXX>