Reputation: 23774
My simple script in Perl
#!/usr/bin/perl
use v5.20.1;
use strict;
use warnings;
$| = 1;
my $string = $ARGV[ 0 ];
my $match = $ARGV[ 1 ];
my $substitute = $ARGV[ 2 ];
$string =~ m/match/g; # just for capturing the pattern
$string =~ s/$match/only $substitute/g;
say "\$1[itself] == $1";
say "\$substitute == $substitute";
say "\$string == $string";
say "prefix == $`";
say "match == $&";
say "suffix == $'";
Input and Output:
$ perl temp 'I have 9 dollars' '(\d+)' '$1'
$1[itself] == 9
$substitute == $1
$string == I have only $1 dollars
prefix == I have
match == 9
suffix == dollars
A thing that I am trying to do is a simple substitution by initializing the match and substitution variable from @ARGV. After that a simple match for initializing the special character such as $1. But when I want to pass the special character $1
from command-line
to the script, it is deducted as a regular string and not the special variable $1 that I need for substitution
If I change the code from:
$string =~ s/$match/only $substitute/g;
to:
$string =~ s/$match/only $1/g;
now it works!
1. Why $1
of the command line is different from $1
in the script?
2. Is there any way to solve it?
A screenshot of my console:
As ikegami suggested I installed and used the String::Substitution and could by using gsub_copy($line, $match, $substitute);
deduced the substitution.
But still I need to use this substitution itself for printing it on the screen and colorize it for illustration that what happens.
In fact this purpose, is part of a rename script that read all file and by call rename
function, changes the name of the files.
As you can see on the screenshot:
instead of for_$1
it should be for_Level
on the screen. So does this module can return what it has deduced?
I am not talking about the sub match of the match group parentheses!
Also the author of the module has said:
This module does not save or interpolate $& to avoid the "considerable performance penalty"
May this screenshot clarify the subject:
Upvotes: 0
Views: 102
Reputation: 385590
Why $1 of the command line is different from $1 in the script?
You're actually asking why
s/.../...$substitute.../
in your script is different than
s/.../...$1.../
in your script. For the same reason that
print($substitute);
is different than
print($1);
and that is that the value of $1
(the captured text) is different than the value of $substitute
($1
).
This is what you need:
use String::Substitution qw( gsub_modify );
gsub_modify($string, $match, $substitue);
That assumes you don't actually need $1
outside of the replacement expression, and that you don't actually need $&
and friends at all. If you do need them, then you can use the following:
use String::Substitution qw( interpolate_match_vars last_match_vars );
$string =~ s/$match/ interpolate_match_vars($substitute, last_match_vars()) /eg;
Upvotes: 2
Reputation: 1623
Obligatory discouragement: don't do this. Basically this is just running eval
on a user-supplied string, which is really a bad idea.
Actual answer: use the ee
modifer (see perlop) to s///
to eval
the string in the right hand part of the expression:
$string =~ s/$match/"\"only $substitute\""/gee
By the way, you don't need to capture the pattern separately, just put the $match
in a capturing group in the s///
expression:
$string =~ s/($match)/"\"only $substitute\""/gee
Upvotes: -1