using $1 in a substitution replacement with variable interpolation

I

imaginarywave

I am trying to use variable interpolation in a replacement string including $1, $2,...
However, I can't get it to expand $1 into the replacement. I eventually will have the
$pattern and $replacement variables be read from a configuration file, but even
setting them manually doesn't work.

In the example script, you can see that the $1 (which should be 'DEF') is not
expanded in $new_name, but it is in $new_name2.

Adding an 'e' flag to the substitution doesn't help.

How do I fix this?

Matt

EXAMPLE CODE:

#!/usr/local/bin/perl
use strict;

my $old_name = 'ABC_DEF_GHI';

my $pattern = 'ABC_(...)_GHI';
my $replacement = 'CBA_${1}_IHG';

# using variables - doesn't work
my $new_name = $old_name;
$new_name =~ s|$pattern|$replacement|;

printf("%s --> %s\n", $old_name, $new_name);


# not using variables - does work
my $new_name2 = $old_name;
$new_name2 =~ s|ABC_(...)_GHI|CBA_${1}_IHG|;

printf("%s --> %s\n", $old_name, $new_name2);


OUTPUT:

ABC_DEF_GHI --> CBA_${1}_IHG
ABC_DEF_GHI --> CBA_DEF_IHG
 
P

Peter Makholm

my $pattern = 'ABC_(...)_GHI';
my $replacement = 'CBA_${1}_IHG';

# using variables - doesn't work
my $new_name = $old_name;
$new_name =~ s|$pattern|$replacement|;

It works to use s/$pattern/qq("$replacement")/ee.

First we do regular interpolation. With /e the replacement is trated as
perl code and therefore not interpolated:

-> s/ABC_(...)_GHI/qq("$replacement")/ee

Given the match we execute once:

-> s/ABC_(...)_GHI/"CBA_${1}_IHG"/e

And once more:

-> s/ABC_(...)_GHI/CBA_DEF_IHG/

Reaching the wanted result.

//Makholm
 
C

Charles DeRykus

I am trying to use variable interpolation in a replacement string including $1, $2,...
However, I can't get it to expand $1 into the replacement. I eventually will have the
$pattern and $replacement variables be read from a configuration file, but even
setting them manually doesn't work.

In the example script, you can see that the $1 (which should be 'DEF') is not
expanded in $new_name, but it is in $new_name2.

Adding an 'e' flag to the substitution doesn't help.

...

#!/usr/local/bin/perl
use strict;

my $old_name = 'ABC_DEF_GHI';

my $pattern = 'ABC_(...)_GHI';
my $replacement = 'CBA_${1}_IHG';

# using variables - doesn't work
my $new_name = $old_name;
$new_name =~ s|$pattern|$replacement|;

printf("%s --> %s\n", $old_name, $new_name);

Perhaps, depending on input string complexity, you could just do this
and avoid a string eval:

(my $new_name=$old_name) = "${^PREMATCH}CBA_${1}_IHG${^POSTMATCH}"
if $old_name =~ m/ABC_(...)_GHI/p;
 
C

Charles DeRykus

Perhaps, depending on input string complexity, you could just do this
and avoid a string eval:

(my $new_name=$old_name) = "${^PREMATCH}CBA_${1}_IHG${^POSTMATCH}"
if $old_name =~ m/ABC_(...)_GHI/p;

Or, simply:

my $new_name = "${^PREMATCH}CBA_${1}_IHG${^POSTMATCH}"
if $old_name =~ m/ABC_(...)_GHI/p;
 
R

Rainer Weikusat

(e-mail address removed) writes:

[...]
#!/usr/local/bin/perl
use strict;

my $old_name = 'ABC_DEF_GHI';

my $pattern = 'ABC_(...)_GHI';
my $replacement = 'CBA_${1}_IHG';

# using variables - doesn't work
my $new_name = $old_name;
$new_name =~ s|$pattern|$replacement|;

printf("%s --> %s\n", $old_name, $new_name);

Using s/// in this way is a little weird. What you are really doing is
to apply a 'pattern' regex to some string in order to extract certain
parts out of it and then, you interpolate these parts into a template
string. I would use something like this for that:

-----------------
#!/usr/local/bin/perl
use strict;

sub interpolate
{
my ($in, $pat, $out) = @_;
my @matches;

@matches = $in =~ /$pat/;
$out =~ s/\$\{([0-9]+)\}/$matches[$1 - 1]/g;

return $out;
}


my $old_name = 'ABC_DEF_GHI';

my $pattern = 'ABC_(...)_(...)';
my $template = '${2}_${1}_IHG';

my $new_name = interpolate($old_name, $pattern, $template);


printf("%s --> %s\n", $old_name, $new_name);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top