SPUG: ifs and whiles and hashes...

Elf Sternberg elf at halcyon.com
Thu Aug 19 11:08:23 CDT 1999


Ryan Forsythe <ryan2 at webrocket.net> writes:

>	if ($dbaseLine =~ m/^\"(?:.*)\",\"(.*)\",\"(.*)\"/)  {

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

        It's not an infinite loop.  What it *is* is perl creating 351
possible different regular expression DFAs and then assigning different
parts of your string, in different lengths, to each one of the 351
possibilities, over and over and over until it gets one that's a match.

        I'm assuming that you're keeping the results of this regexp,
otherwise you wouldn't have parens around them.  If so, there is an
easier way to do this:

        my @res = ();
        $_ = $dbaseLine;
        while(s/^"([^"]*?)",?\s*//) { push @res, $1 }
        if (scalar(@res) == 26) { ... }

        There.  Now @res contains an array that theoretically has 26
elements in it.  The regular expression only has to match one thing
(something contained in quotes that is made up of anything that is not a
quote), that may or may not be followed by a comma.  That element is
destroyed (I put it in a temporary variable anyway so $dbaseLine is not
affected), but the paren match is pushed onto the array.  When you're
out of stuff, the match is unsuccessful and the loop terminates.  You
then test to see if you got 26 things; if you did, you proceed.  The
regular expression here is efficient because it knows to terminate when
is sees the *first* quote symbol.

>btw, is there any shorter way to write that 'if' that still stores
>substrings?

        Shorter?  No.  Smarter?  Absolutely.  With this technique, as
long as you're consistent, you can use lines of different length, or
with some magic use inconsistent quote symbols, like single quotes.

        while((s/^"([^"]+)",?//) || ((s/^'([^']+)',?//)) { 
                push @res, $1
        }


                Elf

Elf M. Sternberg, rational romantic mystic cynical idealist
     MST3K - Help save the saving grace of television.
A.A 1493                        http://www.halcyon.com/elf/

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