What is the RHS of a substitution?

B

Ben Bullock

This question is about substitutions like

s/XYZ/ABC/;

Is there a variable which contains the right hand part (ABC) of the most
recent substitution? I have a series of complex substitutions as part of a
while ( .. ) statement, and I would like to be able to use the right hand
part of the most recent match, but I'm not sure whether there is a simple
way to do this. Thanks for any help.
 
B

Brian McCauley

Ben said:
This question is about substitutions like

s/XYZ/ABC/;

Is there a variable which contains the right hand part (ABC) of the most
recent substitution?

I don't believe so. It seems a rather unusual requirement.
I have a series of complex substitutions as part of a
while ( .. ) statement, and I would like to be able to use the right hand
part of the most recent match, but I'm not sure whether there is a simple
way to do this.

Using the /e qualifier you can put arbitrary Perl code in the RHS, for
example:

use strict;
use warnings;
$_='abc';

my $rhs;
while ( s/([[:lower:]])/$rhs=uc($1)/e ) {
print "$1 => $rhs\n";
}
 
D

Dr.Ruud

Ben Bullock schreef:
This question is about substitutions like

s/XYZ/ABC/;

Is there a variable which contains the right hand part (ABC) of the
most recent substitution? I have a series of complex substitutions as
part of a while ( .. ) statement, and I would like to be able to use
the right hand part of the most recent match, but I'm not sure
whether there is a simple way to do this. Thanks for any help.

You could put the substitutions in an array, like this:

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

use re 'eval' ; # check perlre!

use Data::Dumper ;

my @subst =
( ['ABC', '123'],
['DEF', 'GHI'],
['GHI', '789'],
['XYZ', 'ABC'],
) ;

my @done ;

while (<DATA>)
{
chomp ;

for my $i (0 .. $#subst)
{
my ($f, $t) = ( $subst[$i]->[0],
$subst[$i]->[1],
) ;

s~ $f (?{ push @done,
[
"line $.: $_",
"todo $i: s/$f/$t/",
]
})
~$t~xg
and push @{$done[$#done]}, "result: $_" ;
}
}

print Data::Dumper->Dump( [ \@subst, \@done ],
[qw(*subst *done)]
) ;

__DATA__
wqefewq XYZ skjd
gg g grewg gwg ewrgrewgrewg eagf
qfh GHI qfe ABC ewq DEF ddsf XYZ wfsqf
qckjqcd ABC qlkfjwqf
 
T

Tad McClellan

Ben Bullock said:
This question is about substitutions like

s/XYZ/ABC/;

Is there a variable which contains the right hand part (ABC) of the most
recent substitution?


You can make one:

s/XYZ/ $last_match = 'ABC' /e;
 
D

Dr.Ruud

Dr.Ruud schreef:
my ($f, $t) = ( $subst[$i]->[0],
$subst[$i]->[1],
) ;

By using Lexical::Alias, one can do

alias $subst[$i]->[0], my $f ;
alias $subst[$i]->[1], my $t ;
 
D

Dr.Ruud

Dr.Ruud schreef:
my ($f, $t) = ( $subst[$i]->[0],
$subst[$i]->[1],
) ;

Or use Data::Alias and change it to

my ($f, $t) = alias( $subst[$i]->[0],
$subst[$i]->[1],
) ;

Data::Alias seems to know a few more tricks than Lexical::Alias.
 
B

Ben Morrow

Quoth "Ben Bullock said:
This question is about substitutions like

s/XYZ/ABC/;

Is there a variable which contains the right hand part (ABC) of the most
recent substitution? I have a series of complex substitutions as part of a
while ( .. ) statement, and I would like to be able to use the right hand
part of the most recent match, but I'm not sure whether there is a simple
way to do this. Thanks for any help.

Err, just put it in a variable before you start?

my $foo = 'ABC';
s/XYZ/$foo/;
<more stuff in $foo>

Ben
 
B

Ben Bullock

Ben Morrow said:
Err, just put it in a variable before you start?

my $foo = 'ABC';
s/XYZ/$foo/;
<more stuff in $foo>

Thanks for your help, but this won't work. As I said, I have a series of
complex substitutions in a while statement. The above solution assumes that
the right hand side of the substitution is one fixed string in one
substitution. In fact each RHS involves all kinds of stuff involving $1, $2,
etc., and there is more than one substitution, because a series of
substitutions is being used as the truth test in a while statement. I want
to get the last matched RHS for the most recent round the loop. This is for
a semi-automated batch editing program.

However, the use of s/ /$var = /e does make sense, although I haven't tried
it in practice yet. Thanks to everyone who made a suggestion.
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top