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
|
|
|
|
|