Re: Search for abcNUMBERdef, make it a variable, then do math?
by CountZero (Bishop) on Jan 22, 2011 at 07:45 UTC
|
Every regex starts an new sequence of $1, $2, $3, ... again. Therefore each of your captures goes into the same $1. You do capture all the numbers, but overwrite them with the capture of the next regex and therefore it ends up with the last capture in $1 and all other still zero (in numeric context).As a best practice, you should waste no time or processor cycles before you put the results of the captures stored in $1 and its brethren into regular variables. Never ever trust them to "keep" their values. A subroutine far far away in another module my decide at any moment to trash them for its own use.
CountZero A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James
| [reply] [d/l] [select] |
|
$id4 =~ /yesterday(\d+)yesterday/;
my $ans2 = $2 * .40;
$final2 = ($ans2 / 100);
Jesse Smith: Further to CountZero's reply: in the above quoted and in subsequent steps in the OPed code, the capture variable $2 (and subsequently $3 $4) is used in a calculation, but there is no second (or third or fourth) capture group to populate this variable with a defined value. The fact it is undefined would have been made evident to you had you been using warnings (and strictures for good measure – and diagnostics for even better measure since you are learning Perl):
use warnings;
use strict;
use diagnostics;
See perlre, perlrequick, perlretut, perlreref for regular expression (re) on-line documentation, or perldoc perlre etc for local installation documentation.
| [reply] [d/l] [select] |
Re: Search for abcNUMBERdef, make it a variable, then do math?
by PeterPeiGuo (Hermit) on Jan 22, 2011 at 06:15 UTC
|
Use a hash or array to index information, don't make the index part of your variable name.
| [reply] |
Re: Search for abcNUMBERdef, make it a variable, then do math?
by cdarke (Prior) on Jan 22, 2011 at 06:18 UTC
|
make it a variable, for example
$12345
Not sure why you would want to, but you cannot create a variable starting with a numeric explicitly, you would have to have 12,345 capturing parentheses groups.
I'm not certain what it is you want, but would this do? #!/usr/bin/perl
use warnings;
use strict;
my %nums;
@nums{qw(today yesterday this last)} = undef;
my $alts = join('|',keys %nums);
while (<DATA>) {
/($alts)(\d+)\1/;
$nums{$1} = $2;
}
for my $key (keys %nums) {
my $ans = ($nums{$key} * 0.4)/100;
print "$key: $ans (from $nums{$key})\n"
}
__DATA__
Today: today408today
Clicks: 34
Yesterday: yesterday555yesterday
Clicks: 61
This Month: this11360this
Clicks: 812
Last Month: last5350last
Clicks: 454
| [reply] [d/l] |
|
I'll try that out and post back. I'm just trying to change
Today: today408today
Yesterday: yesterday555yesterday
This Month: this11360this
Last Month: last5350last
in to
Today: 1.63
Yesterday: 22.22
This Month: 45.44
Last Month: 21.40
40% of what the number is, with the period added.
By doing this math for each of them. For example...
Today: today408today
would do
408*.4/100=1.63200
with the '200' part taken off.
| [reply] [d/l] |
|
root@wor [/home/site82/public_html/cgi-bin]# perl stats.cgi
Prototype mismatch: sub main::head: none vs ($) at stats.cgi line 19
today: 0 (from )
last: 0 (from )
this: 0 (from )
yesterday: 0 (from )
The first part of the script is
if (length ($ENV{'QUERY_STRING'}) > 0){
$buffer = $ENV{'QUERY_STRING'};
@pairs = split(/&/, $buffer);
foreach $pair (@pairs){
($name, $value) = split(/=/, $pair);
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg
+;
$in{$name} = $value;
}
}
my $id = param('id');
use LWP::Simple;
$id2 = get ("http://www.domain.com/stats.php?id=$id");
and Line 19 is
use LWP::Simple; | [reply] [d/l] [select] |
|
Re: Search for abcNUMBERdef, make it a variable, then do math?
by Albannach (Monsignor) on Jan 22, 2011 at 15:04 UTC
|
Unless you need to store the values for later use, I'd do it this way:
use strict;
use warnings;
while(<DATA>) {
if(/([\w\s]+:)\s([a-z]+)(\d+)\2/) {
print "$1 ", sprintf("%5.2f\n",$3*0.4/100);
}
}
__DATA__
Today: today408today
Clicks: 34
Yesterday: yesterday555yesterday
Clicks: 61
This Month: this11360this
Clicks: 812
Last Month: last5350last
Clicks: 454
which gives
Today: 1.63
Yesterday: 2.22
This Month: 45.44
Last Month: 21.40
Edited: Removed unnecessary extra colon in print (I had captured it already from the input) and inserted actual output generated - duh!
--
I'd like to be able to assign to an luser
| [reply] [d/l] [select] |
|
#!/usr/bin/perl
use warnings;
use strict;
if (length ($ENV{'QUERY_STRING'}) > 0){
my($buffer) = $ENV{'QUERY_STRING'};
my(@pairs) = split(/&/, $buffer);
foreach my($pair) (@pairs){
($name, $value) = split(/=/, $pair);
my($value) =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1)
+)/eg;
$in{$name} = $value;
}
}
my($id) = param('id');
use LWP::Simple;
$id2 = get ("http://www.domain.info/stats.php?id=$id");
$id2 =~ s*\[Yesterday\] *Yesterday: *g;
while(<DATA>) {
if(/([\w\s]+:)\s([a-z]+)(\d+)\2/) {
print "$1 ", sprintf("%5.2f\n",$3*0.4/100);
}
}
spits out
Missing $ on loop variable at stats.cgi line 9.
on SSH.
| [reply] [d/l] |
|
...
foreach my($pair) (@pairs){
...
This is not valid Perl code. The valid Perl code would be (note the lack of parentheses)
foreach my $pair (@pairs){
But in all seriousness, why are you trying to do what is CGI.pm's job? Just use CGI; and then query $q->Vars to get a hash of parameters passed to your script. Don't parse query strings yourself. | [reply] [d/l] [select] |
|
|
|
Its because you keep including that ENV{'QUERY_STRING'} garbage, get rid of it
| [reply] |