Search and replace problem

I

ironmanda

I'm trying to build a general way of handling search and replace
of strings. The regexp in the commented out part works perfectly.
But, the foreach part doesn't work. The thing is, \1 is being
interpreted literally. Any ideas?

David

#!/usr/local/bin/perl

my $str="http://www.xxx.com/yyy/zzz/25331/2";

$repurl{"([0-9]*)\\/[0-9]+\$"}="\\1";

# $str=~s/([0-9]*)\/[0-9]+$/\1/g;
# print "$str\n";
# exit 0;

foreach $key (sort keys %repurl) {
print "$key - $repurl{$key}\n";
$str=~s/$key/$repurl{$key}/g;
}

print "$str\n";
 
D

David Squire

I'm trying to build a general way of handling search and replace
of strings. The regexp in the commented out part works perfectly.
But, the foreach part doesn't work. The thing is, \1 is being
interpreted literally. Any ideas?

Ermmm... read the documentation on Perl regular expressions?

perldoc perlre
perldoc perlretut

In particular, look at the difference between backreferences (\1, \2,
etc.) used within a regular expression, and match (or capture) variables
($1, $2, etc.) used *outside* regular expressions (e.g. in a replacement
string).


DS
 
P

Paul Lalli

I'm trying to build a general way of handling search and replace
of strings. The regexp in the commented out part works perfectly.
But, the foreach part doesn't work. The thing is, \1 is being
interpreted literally. Any ideas?

David

#!/usr/local/bin/perl

my $str="http://www.xxx.com/yyy/zzz/25331/2";

$repurl{"([0-9]*)\\/[0-9]+\$"}="\\1";

# $str=~s/([0-9]*)\/[0-9]+$/\1/g;
# print "$str\n";
# exit 0;

Run this part again, and this time turn warnings on. Why aren't they
turned on to begin with?

Does that warning help you figure out what you should have done
instead?

Paul Lalli
 
J

John W. Krahn

I'm trying to build a general way of handling search and replace
of strings. The regexp in the commented out part works perfectly.
But, the foreach part doesn't work. The thing is, \1 is being
interpreted literally. Any ideas?


#!/usr/local/bin/perl

my $str="http://www.xxx.com/yyy/zzz/25331/2";

$repurl{"([0-9]*)\\/[0-9]+\$"}="\\1";

# $str=~s/([0-9]*)\/[0-9]+$/\1/g;
# print "$str\n";
# exit 0;

foreach $key (sort keys %repurl) {
print "$key - $repurl{$key}\n";
$str=~s/$key/$repurl{$key}/g;
}

print "$str\n";

$ perl -Mwarnings -Mstrict -e'
my $str = q[http://www.xxx.com/yyy/zzz/25331/2];

my %repurl = ( q[(\d*)/\d+$] => q[$1] );

for my $key ( sort keys %repurl ) {
print "$key - $repurl{$key}\n";
$str =~ s/$key/$repurl{$key}/eeg;
print "$str\n";
}
'
(\d*)/\d+$ - $1
http://www.xxx.com/yyy/zzz/25331



John
 
I

ironmanda

Thanks John, this worked. They was the /eeg on
the search and replace. Much appreciated.

David
I'm trying to build a general way of handling search and replace
of strings. The regexp in the commented out part works perfectly.
But, the foreach part doesn't work. The thing is, \1 is being
interpreted literally. Any ideas?


#!/usr/local/bin/perl

my $str="http://www.xxx.com/yyy/zzz/25331/2";

$repurl{"([0-9]*)\\/[0-9]+\$"}="\\1";

# $str=~s/([0-9]*)\/[0-9]+$/\1/g;
# print "$str\n";
# exit 0;

foreach $key (sort keys %repurl) {
print "$key - $repurl{$key}\n";
$str=~s/$key/$repurl{$key}/g;
}

print "$str\n";

$ perl -Mwarnings -Mstrict -e'
my $str = q[http://www.xxx.com/yyy/zzz/25331/2];

my %repurl = ( q[(\d*)/\d+$] => q[$1] );

for my $key ( sort keys %repurl ) {
print "$key - $repurl{$key}\n";
$str =~ s/$key/$repurl{$key}/eeg;
print "$str\n";
}
'
(\d*)/\d+$ - $1
http://www.xxx.com/yyy/zzz/25331



John
 
B

Brian McCauley

I'm trying to build a general way of handling search and replace
of strings. The regexp in the commented out part works perfectly.
But, the foreach part doesn't work. The thing is, \1 is being
interpreted literally. Any ideas?

Others have pointed out that you meant $1 not \1 and also that Perl
would have told you this if you'd let it so I'm going to take it as
read that \1 as been replaced by $1.

You are not the first person to post here with substancially the same
desire.

Indeed at YAPC::Europe::2004 I gave a lightning talk about all the
different varients of this thread that I'd come accross over the
preceding couple of years.

http://birmingham.pm.org/talks/brian/faq-short/Intro.html
#!/usr/local/bin/perl

my $str="http://www.xxx.com/yyy/zzz/25331/2";

$repurl{"([0-9]*)\\/[0-9]+\$"}="\\1";

You are not using the natural representation of things.

You never look things up in %repurl by key so a hash is not the natural
data structure. It is just a list of pairs. So the natural
representation is more like:

push @repurl, [ "([0-9]*)\\/[0-9]+\$" => "\$1" ];

But the natural representation of a regex for later evaluation is not a
string, it's a precompiled regex. And the natural representation of an
expression for later evaluation is not a string either, it's precomiled
code.

push @repurl, [ qr/([0-9]*)\/[0-9]+\$/ => sub { $1} ];

foreach my $subst (@repurl) {
$str =~ s/$subst->[0]/$subst->[1]->()/eg;
}

But of course fundamentally you have to ask yourself why you are trying
to write something "general" when you started off with something
general?

Why not just write Perl? Be aware that any solution that ends up using
eval() untilately allows any Perl anyhow so you are not restricting
what can be done.

Why not simply express what you want in Perl in the first place rather
than inventing your own "small language" that isn't any easier to write
than Perl nor is it more restrictive than Perl.

push @repurl, sub { s/([0-9]*)\/[0-9]+\$/$1/g };

foreach my $subst (@repurl) {
$subst->() for $str;
}
 
B

Brian McCauley

John said:
my %repurl = ( q[(\d*)/\d+$] => q[$1] );
$str =~ s/$key/$repurl{$key}/eeg;

Be aware that this is interpreting the q[$1] as a simple Perl
expression to be evaluated rather than as a string to undergo
interpolation.

If the replacement had been q[foo$1] then this would have caused a
runtime error but because it would be inside an eval() and you are not
checking $@ the error would simply be ignored and the replacement would
be null.

I prefer to use

# http://birmingham.pm.org/talks/brian/faq-short/Fixed.html

s{$key}{
chop( my $s = eval "<<_END_\n$repurl{$key}\n_END_" );
die $@ if $@;
$s;
}eg;
 
T

Ted Zlatanov

You are not the first person to post here with substancially the same
desire.

Indeed at YAPC::Europe::2004 I gave a lightning talk about all the
different varients of this thread that I'd come accross over the
preceding couple of years.

So it's a QASFTBMGALTAI*

You could have just said "QASFTBMGALTAI" and everyone would know what
you meant. Geez, stop wasting bandwidth.

Ted

* Question Asked So Frequently That Brian McCauley Gave A Lightning
Talk About It
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top