Re: [SLUG] Perl Question
On Wed, Apr 02, 2008 at 03:09:44PM +1100, Peter Abbott wrote: > Can anyone with greater knowledge than myself explain this regex > behaviour. > [ ... ] > if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d > \d).*?(\d*\.\d\d)L/) { > $box = $1; > $name = $2; > $name =~ s/\.//; > $place = $4; > $time = $5; > $margin = $6; > } > Undoubtedly something simple that a self taught dummy has failed to > grasp. Doing s/// for $name there resets the $1, $2, .. counters Matt -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] Perl Question
Rick Welykochy wrote: Peter Abbott wrote: if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d \d).*?(\d*\.\d\d)L/) { $box, = $1; $name = $2; $place = $4; $time = $5; $margin = $6; $name =~ s/\.//; } Please write maintainable code that is easy to understand. I'll put my money where my mouth is ... $match = qr/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*). ... etc/; if (m/$match/) { ($box,$name,$place,$time,$margin) = ($1,$2,$4,$5,$6); $name =~ s/\.//; } i.e. my rule of matching: grab the $placement variables in the statement, to be sure, to be sure :) The qr/.../ creates a pattern match, precompiled. And it can be used multiple times in your code. Easier to maintain. It's the one thing missing from python: ease of handling regexs. Yes, yes, there is the 're' package, but that is an O-O implementation. ot part of the language. It is for that reason alone that my GLPs (grungy little programs) are still whipped up in perl instead of python. cheers rickw -- Rick Welykochy || Praxis Services || Internet Driving Instructor The best way to accelerate a PC is 9.8 m/s2 -- anon -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] Perl Question
Peter Abbott wrote: if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d \d).*?(\d*\.\d\d)L/) { $box = $1; $name = $2; $place = $4; $time = $5; $margin = $6; $name =~ s/\.//; } correcto However if the $name substitution is inserted above $place like so it fails to allocate values to $place, $time and $margin. if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d \d).*?(\d*\.\d\d)L/) { $box = $1; $name = $2; $name =~ s/\.//; $place = $4; $time = $5; $margin = $6; } incorrecto and hard to maintain You've also introduced a very subtle bug that I could not, at first glance, see. The $name substitution resets $1 ... $6. Please write maintainable code that is easy to understand. I wouldn't want to be given the second code example buried amongst 1000+ lines of perl and then asked to fix "the obscure bug". cheers rickw -- Rick Welykochy || Praxis Services || Internet Driving Instructor The best way to accelerate a PC is 9.8 m/s2 -- anon -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
[SLUG] Perl Question
Thanks to all who replied. I am the wiser now. - Regards, Peter. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] Perl Question
On Wed, Apr 2, 2008 at 1:09 AM, Peter Abbott <[EMAIL PROTECTED]> wrote: > [..snip..] > if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d > \d).*?(\d*\.\d\d)L/) { >$box = $1; >$name = $2; >$name =~ s/\.//; >$place = $4; >$time = $5; >$margin = $6; >} > Undoubtedly something simple that a self taught dummy has failed to > grasp. > Hi Peter, I'm not too sure about this, but I believe when you do "$name =~", you're effectively starting a new regular expression which means it clears $1, $2, $3, $4, etc (unless you use brackets inside the new regular expression). Maybe someone else can explain it better than me? :-) HTH! - Gonzalo -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] Perl Question
On Wed, Apr 2, 2008 at 3:09 PM, Peter Abbott <[EMAIL PROTECTED]> wrote: > Can anyone with greater knowledge than myself explain this regex > behaviour. > This code segment works as intended: > > > if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d > \d).*?(\d*\.\d\d)L/) { > $box = $1; > $name = $2; > $place = $4; > $time = $5; > $margin = $6; > $name =~ s/\.//; > } > > However if the $name substitution is inserted above $place like so it > fails to allocate values to $place, $time and $margin. > > > if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d > \d).*?(\d*\.\d\d)L/) { > $box = $1; > $name = $2; > $name =~ s/\.//; > $place = $4; > $time = $5; > $margin = $6; > } > Undoubtedly something simple that a self taught dummy has failed to > grasp. I suspect that the added line resets the back-references (the "$1".."$6"). Try moving it under the $margin assignment (i.e. until after you are done with the back-references). --Amos -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
[SLUG] Perl Question
Can anyone with greater knowledge than myself explain this regex behaviour. This code segment works as intended: if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d \d).*?(\d*\.\d\d)L/) { $box = $1; $name = $2; $place = $4; $time = $5; $margin = $6; $name =~ s/\.//; } However if the $name substitution is inserted above $place like so it fails to allocate values to $place, $time and $margin. if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d \d).*?(\d*\.\d\d)L/) { $box = $1; $name = $2; $name =~ s/\.//; $place = $4; $time = $5; $margin = $6; } Undoubtedly something simple that a self taught dummy has failed to grasp. Regards, Peter. Happy & proud to be, 100% Microsoft free. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] Perl question
Alexander Samad wrote: Quick question How can I do this print "This is the value ".$x->SomeFunc(); as print "This is the value $x->SomeFunc()"; You can go: print "This is the value @{[$x->SomeFunc()]}"; But are you sure you want to do that? ;) Mick. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
[SLUG] Perl question
Quick question How can I do this print "This is the value ".$x->SomeFunc(); as print "This is the value $x->SomeFunc()"; seems like the substition stops at the - on the second line Alex signature.asc Description: Digital signature -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] Perl question
Crossfire was once rumoured to have said: > But given what it looks like you're trying to do, you probably want to > keep many filehandles open at once.. [one for each user], you probably > want a construct like: > > my %userfh; > foreach my $user (@users) { > $userfh[$user] = new FileHandle ">> $user"; # note, this is WRONG. > if (defined $userfh[$user]) { > > } > } GRAH! I'm on crack! this is what I get for answering questions before I leave for work. just replace all my ravings of $userfh[$user] with $userfh{$user}! [x] is an array subscript. {x} is a hash subscript. -- --==-- Crossfire | This email was brought to you [EMAIL PROTECTED] | on 100% Recycled Electrons --==-- -- SLUG - Sydney Linux User Group Mailing List - http://slug.org.au/ More Info: http://slug.org.au/lists/listinfo/slug
Re: [SLUG] Perl question
Michael Lake was once rumoured to have said: > Hi All, > > OK this is a perl Q not Linux but it's Sunday night. :-) > Am having probs opening several files in a perl script using indirect > filehandles. [Snip] > > foreach $user (@users) > { > $fh = new FileHandle ">> $user"; > $fhUser = $fh.$user; > if (defined $fhUser) { > print $fhUser "Hi $user\n"; > print $fhUser $subject; > print $fhUser "Date File from IP Address\n"; > } > else { > print "Cannot open file $user for writing\!"; > } > } Drop the $fhUser bit, - this section is *all* wrong. you use: print $fh to print to the file, you don't mangle the object rej. But given what it looks like you're trying to do, you probably want to keep many filehandles open at once.. [one for each user], you probably want a construct like: my %userfh; foreach my $user (@users) { $userfh[$user] = new FileHandle ">> $user"; # note, this is WRONG. if (defined $userfh[$user]) { } } you can then close all of these filehandles using: foreach my $user (keys %userfh) { $userfh[$user]->close; } > Then all I want to do is the processing > > while (<>) > { > Here is where I do processing and writing stuff to those open > files > print $fhUser "$words[3] $words[4] $words[6] from $words[0]\n"; > etc.. > } Looks fine... 'cept that $fhUser bit should be $userfh[$user] if I'm understanding what you're trying to do. > > and then close all those open files... > foreach $user (@users) > { > print "Total logins: $users{$user}\n"; > $fhUser->close; > } More crack. $foo{blah} construcuts are valid for hashes, not arrays. > It's just that I have not used indirect filehandles before and the > Learning Perl book only has examples of direct filehandles. You've got more than just that wrong. I seriously suggest you brush up on Perl Operators, datatypes and start using perldoc more. C. -- --==-- Crossfire | This email was brought to you [EMAIL PROTECTED] | on 100% Recycled Electrons --==-- -- SLUG - Sydney Linux User Group Mailing List - http://slug.org.au/ More Info: http://slug.org.au/lists/listinfo/slug
[SLUG] Perl question
Hi All, OK this is a perl Q not Linux but it's Sunday night. :-) Am having probs opening several files in a perl script using indirect filehandles. #!/usr/bin/perl -w # This script reads the ASF's Apache log files and extracts accesses by specific users. These accesses are regularly emailed to the users by a cron script. use strict; use FileHandle; my $fileUsers="users"; # I use IN for the file handle for this. my $fh; my $fhUser; # File handle for files. # Here is where I open a user list and read it in. Im used to this way. # I am used to using direct filehandles like this ie IN. open (IN, "$fileUsers") || die "Cannot open file $fileUsers for reading\!"; while() { ($users_login, $users_name, $users_email) = split(/:/, $_); push(@users, $users_login); } close (IN) || die "Cannot close file $fileUsers\!"; All the above is OK. Now here I have probs. For each user I want to open a file with the filename being the same as the name of the user. I want to have this file open for the duratiion of parsing an Apache log file and write to each one so I need a filehandle for each user file. If I try this below: foreach $user (@users) { $fhUser = "handle".$user; open ($shUser, ">> $user") || die "Cannot open file $user for reading\!"; print $fhUser "Hi $user\n"; } I get the error upon running of: "Can't use string ("handlemike") as a symbol ref while "strict refs" in use at ./process line 90." So I tried this from the Programming Perl book, chap 7 using the FileHandle method: foreach $user (@users) { $fh = new FileHandle ">> $user"; $fhUser = $fh.$user; if (defined $fhUser) { print $fhUser "Hi $user\n"; print $fhUser $subject; print $fhUser "Date File from IP Address\n"; } else { print "Cannot open file $user for writing\!"; } } and I get "Can't use string ("FileHandle=GLOB(0x1202e1600)mike") as a symbol ref while "strict refs" in use at ./process line 82." Then all I want to do is the processing while (<>) { Here is where I do processing and writing stuff to those open files print $fhUser "$words[3] $words[4] $words[6] from $words[0]\n"; etc.. } and then close all those open files... foreach $user (@users) { print "Total logins: $users{$user}\n"; $fhUser->close; } It's just that I have not used indirect filehandles before and the Learning Perl book only has examples of direct filehandles. Mike -- Michael Lake Active caver, Linux enthusiast and interested in anything technical. Safety Convenor, Australian Speleological Federation Owner, Speleonics (Australia) -- SLUG - Sydney Linux User Group Mailing List - http://slug.org.au/ More Info: http://slug.org.au/lists/listinfo/slug