Reputation: 49567
I am trying to replace whitespaces
in a string after matching it against a regular expression.
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;
}
Now when I run the above code I get Modification of a read-only value attempted
. Now if I store the value of $1
in a variable than try to perform a substitution on that variable it works fine.
So, is there any way I can perform a substitution in place without creating a new temporary variable.
PS: Can someone show me how to write the above code as one-liner because I am not able to :)
Upvotes: 3
Views: 1270
Reputation: 67231
You can try this:
perl -pi -e 'if($_=~/Season\s\d+\sEpisode\s\d/){s/\s+//g;}' file
tested below:
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>
Upvotes: -1
Reputation: 67918
If you use a post-script for
loop to create a local instance of $_
, you can chain your substitution with a print (using a comma) to achieve a pre-print processing of the match.
Note that parentheses are not required when using the global /g
option. Also note that this makes your if-statement redundant, since any non-match will return an empty list to your for
loop.
perl -nlwe 's/\s+//g, print for /Season\s+\d+\s+Episode\s+\d+/g;' yourfile.txt
In your script, it looks like this. Note that the if-statement is replaced with a for loop.
for ( $string =~ /Season\s+\d+\s+Episode\s+\d+/g ) {
s/\s+//g; # implies $_ =~ s/\s+//g
say; # implies say $_
}
This is mainly to demonstrate the one-liner. You may insert a lexical variable instead of using $_
, e.g. for my $match ( ... )
if you want increased readability.
Upvotes: 2
Reputation: 126722
It looks like you want to compress Season 1 Episode 1
to Season1Episode1
within the original string
This can be done conveniently using the @-
and @+
together with a call to substr
as an lvalue
This program shows the idea
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;
}
output
watch download Buffy the Vampire Slayer Season1Episode1 Gorillavid
You don't say why you want to write this in a single line, but if you must then this will do it for you
perl -pe '/Season\s*\d+\s*Episode\s*\d+/ and substr($_, $-[0], $+[0] - $-[0]) =~ s/\s+//g' myfile
Upvotes: 3
Reputation: 22421
Don't mess with special variables and just capture the data you want, while construction output yourself.
$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");
}
Upvotes: 5