Perl Regex:尝试修改只读值

时间:2012-09-10 12:29:03

标签: regex perl

我尝试在将字符串与正则表达式匹配后替换字符串中的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:有人可以告诉我如何将上述代码编写为单行代码,因为我无法:)

5 个答案:

答案 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>