SPUG: ifs and whiles and hashes...
Ken McGlothlen
mcglk at serv.net
Wed Aug 18 19:18:37 CDT 1999
Ryan Forsythe <ryan2 at webrocket.net> writes:
| i'm writing a program which opens a text file, searches each line, and
| extracts data from it and sticks it in a hash...well, that's what it's
| supposed to do. here's a simplification of the loop i'm having problems
| with:
|
| while (defined($dbaseLine = <DATABASE>)) {
|
| #code here...
|
| if ($dbaseLine =~ m/^\"(?:.*)\",\"(.*)\",\"(.*)\"/) {
|
| $hash{'key1'} = $1;
| $hash{'key2'} = $2;
| #etc...
| } else {
| next;
| }
| }
|
| however, my program has 26 of these '\"(.*)\",' in the 'if ($dbaseLine...'
| test. when i run it, it assigns the $dbaseLine variable okay, but when it
| gets to that if test, it locks up and i watch perl's cpu time go up to 99%.
| i'm assuming it's getting in an infinite loop, but why? i don't understand
| how an if can cause and infinite loop, especially when it doesn't affect the
| test variable of the while it's wrapped in (if that makes any sense to
| anybody :))
Well, it's not the "if" statement itself---it's the matching process. Perl is
attempting all sorts of possible combinations in this case to figure out if the
regexp fits (I posted a similar problem to this list just the other day).
You might do well to replace the .* expression with [^"]*, which would at least
stop at the first non-quote character.
However, what I would probably do in this case is try to figure out what
actually makes a line qualify as a $dbaseLine. What are you trying to exclude?
If all you're worried about is blank lines, that's easy enough to handle:
while( defined( $dbaseLine = <DATABASE> ) ) {
chomp( $dbaseLine );
next if( $dbaseLine eq "" );
...
}
for example.
As far as handling the breaking up of the variable itself, I might recommend
going with something else that will work a lot faster. For example:
$dbaseLine = s/^"//; # Trim opening quote.
$dbaseLine = s/"$//; # And the trailing one.
@vals = split( /","/, $dbaseLine ) # Break it up.
$count = 0;
for( @vals ) {
++$count;
$hash{"key$count"} = $_;
}
More code, but avoids the endless attempts to match the complex regex.
---Ken
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
POST TO: spug-list at pm.org PROBLEMS: owner-spug-list at pm.org
Seattle Perl Users Group (SPUG) Home Page: http://www.halcyon.com/spug/
SUBSCRIBE/UNSUBSCRIBE: Replace ACTION below by subscribe or unsubscribe
Email to majordomo at pm.org: ACTION spug-list your_address
More information about the spug-list
mailing list