For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > January 2006 > about eval and stdin









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author about eval and stdin
Adriano Allora

2006-01-10, 4:02 am

hi to all,
a friend of mine ask me for a perl script to change regexp patterns in
some texts (he can learn regexp, but I suppose he won't learn perl). So
I start write this one to him.
I have a problem:

==> with pattern = (dir)ectory and replacement = $1, why the script
does not eval $1 as "dir"? how I can change the script to make it works
as I want?


#!/usr/bin/perl -w
$^I ='_old';
print "pattern: ";
$pattern = <STDIN>;
chomp($pattern);
print "replacement: ";
$replacement = <STDIN>;
chomp($replacement);
print "\n print \"s\" to confirm substitution; print \"n\" to avoid it
print \"n\" \n\n";
while(<> )
{
$choice = "";
if(/$pattern/gi)
{
eval $replacement if $replacement eq "$1";
print STDOUT "I'd subsitute this one => ". $_;
$choice = <STDIN>;
chomp($choice);
}
s/$pattern/$replacement/gi if $choice eq "s";
print;
}

thank you all,

alladr


|^|_|^|_|^| |^|_|^|_|^|
| | | |
| | | |
| |*\_/*\_/*\_/*\_/*\_/* | |
| |
| |
| |
| http://www.e-allora.net |
| |
| |
**************************************

John Doe

2006-01-10, 4:02 am

Adriano Allora am Montag, 2. Januar 2006 12.48:
> hi to all,
> a friend of mine ask me for a perl script to change regexp patterns in
> some texts (he can learn regexp, but I suppose he won't learn perl). So
> I start write this one to him.
> I have a problem:
> ==> with pattern = (dir)ectory and replacement = $1, why the script
> does not eval $1 as "dir"? how I can change the script to make it works
> as I want?


because there is no $1 at the point you test it. You get an $1 by putting '()'
in a match/substitution.

btw: What would be the purpose of evaling it?

> #!/usr/bin/perl -w


add
use strict;

here and declare your variables with my (good style).

> $^I ='_old';
> print "pattern: ";


Single quotes are sufficient here and on several places below, since nothing
is interpolated into the string.

> $pattern = <STDIN>;
> chomp($pattern);
> print "replacement: ";
> $replacement = <STDIN>;
> chomp($replacement);
> print "\n print \"s\" to confirm substitution; print \"n\" to avoid it
> print \"n\" \n\n";


The above print statements are a bit messy imho.
Maybe you also want to give out 'type' instead of 'print'.

> while(<> )
> {
> $choice = "";
> if(/$pattern/gi)


the g modifier is not necessary here, because the if branch is executed on one
or more occurences of $pattern.

> eval $replacement if $replacement eq "$1";
> print STDOUT "I'd subsitute this one => ". $_;
> $choice = <STDIN>;
> chomp($choice);
> }
> s/$pattern/$replacement/gi if $choice eq "s";
> print;
> }


The script behaves a bit strange by echoing most of the input.
You could make it more userfriendly by avoiding this and give out messages
what to do at the appropriate places.


hth, joe
Timothy Johnson

2006-01-10, 4:02 am


Ok, I think I see the problem. I re-wrote your script a little (watch =
for line breaks), and you should be able to see what the problem is when =
you run it. Your substitution isn't doing what you think it's doing. =
In the future it always helps to add these kinds of "debug lines" when =
it seems like your variables aren't doing what they're supposed to, or =
use an actual perl debugger to see what is happening in real time.

You could try replacing '$pattern' with '$1' in the substitution, but =
depending on how complex your regexes are, you might not get the results =
you want. In the example below you could end up replacing all instances =
of 'ch', when that's clearly not was intended. However, if you just =
want to find all instances of a text string and replace it, it will work =
fine to use $1.


#######################################

use strict;
use warnings;

$^I =3D'_old';=20

print "\n\n";
print "Enter a pattern to look for,\n";
print "and some text to replace it with.\n\n";
print "PATTERN: ";=20
my $pattern =3D <STDIN>;=20
chomp($pattern);=20

print "REPLACEMENT: ";=20
my $replacement =3D <STDIN>;=20
chomp($replacement);=20

print "\n\n";
while(<> ){=20
my $choice;=20
if(/$pattern/gi){
print STDOUT "Pattern Found!\n\n";
print STDOUT "\t\$_ =3D> $_\n";
print STDOUT "\t\$1 =3D> $1\n\n";
=09
print STDOUT "\tType \"s\" to confirm substitution,\n";
print STDOUT "\t or press any other key to cancel: ";
$choice =3D <STDIN>;=20
chomp($choice);=20
=09
print STDOUT "\n\tCOMMAND: s/$pattern/$replacement/gi if \$choice eq =
\"s\"\n";
s/$pattern/$replacement/gi if $choice eq "s";
print STDOUT "\n\n";
}
print;=20
}

########################################
##

OUTPUT:

C:\Documents and Settings\tjohnson\Desktop>replace.pl cppb.txt


Enter a pattern to look for,
and some text to replace it with.

PATTERN: Te([^ ]+).*support
REPLACEMENT: sticular


Pattern Found!

$_ =3D> Tech Support

$1 =3D> ch

Type "s" to confirm substitution,
or press any other key to cancel: s

COMMAND: s/Te([^ ]+).*support/sticular/gi if $choice eq "s"



________________________________________

From: Adriano Allora [mailto:all.adr@e-allora.net]=20
Sent: Tuesday, January 03, 2006 10:03 AM
To: Timothy Johnson
Subject: Re: about eval and stdin

hi,=20

Il giorno 03/gen/06, alle 18:16, Timothy Johnson ha scritto:=20

I think when you include the parentheses in your pattern $1 is being set =
to the value inside the partentheses.=A0 It's as if you typed:=20
=A0=20
=A0=A0=A0 if(/(dir)ectory/gi)=20
=A0=20
which will set $1 to 'dir', which is probably not what you want.=20

ehm, instead it's exactly what I want (selecting a part of the pattern =
as substitution). My problem is that the script sets $1 =3D "$1" and I =
ignore why.=20

thanks,=20

alladr=20

=A0=20
I think you can avoid this if you change the line to:=20
=A0=20
=A0=A0=A0 if(/($pattern)/gi)=20
=A0=20


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com