Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

Infinite loop regex

by Baz (Friar)
on Aug 04, 2002 at 01:58 UTC ( #187433=perlquestion: print w/replies, xml ) Need Help??

Baz has asked for the wisdom of the Perl Monks concerning the following question:

Why is this an infinite loop?
my $count; while($response->content =~ /pcd=BT(\d+)/g) { print $count++,$1,"\n"; }
I tried it with an IF, and it printed the first match fine.

Replies are listed 'Best First'.
Re: Infinite loop regex
by MrNobo1024 (Hermit) on Aug 04, 2002 at 02:06 UTC
    You're calling the object method again every time, so //g resets to the beginning every time. You should assign it to a variable:
    my $content = $response->content; while($content =~ /pcd=BT(\d+)/g)


      TIMTOWTDI... I would use a foreach loop instead of while. foreach will build the list before the loop runs then iterate, so once the list is finished the loop will exit. One call to the subroutine, no temporary variables, ie:

      foreach ($response->content =~ /pcd=BT(\d+)/g) { print $count++,$1,"\n"; }
      Thnaks, I was going to do that actually but then I thought it didnt make sence...I think I need to read up on Perl object. ;)
        Think about it this way... every time you call the method on your object, it's basically like calling a subroutine which returns a string (because it does). However, because you're calling that method while the regex matches, it starts anew each time...

        You: Ok, run the method.
        Regex: Wow, here's match #1... return $1
        You: print(); Ok, run the method...
        Regex: Wow, here's match #1... return $1

        Wash, rinse, repeat...

        Make sense?

        A reply falls below the community's threshold of quality. You may see it by logging in.

        Perl keeps the position of regexp-matching in mind: bound to a variable! See:

        my $var = 'a111a222a333'; $var =~ m/a(\d+)/g and print $1 # prints '111'

        The regex ended after the three 1es, at position 4. This position ist stored by perl inside tha variable. You can retrieve it via pos($var). Read on it in `perldoc -f pos`

        $var =~ m/a(\d+)/g and print $1; #will now print '222' because the regex starts at # pos($var) (which is 4) #You can also use pos() as an lvalue pos($var) = 0; $var =~ m/a(\d+)/ and print $1; # NO, doesn't print '333' # but '111' because pos($var) wat set to 0 and so # the regexp startsat positin 0 again

        Why do I tell you so? If you generate the strng again, the pos() will allways go back to 0, because you do not always match on the same variable, but on a new variable each time.

Re: Infinite loop regex
by YuckFoo (Abbot) on Aug 04, 2002 at 12:08 UTC
    Unless there is an advantage to getting the matches one at a time, I'd get them all at once by assigning to a list.


    #!/usr/bin/perl $string = 'a=111a=222a=333'; @list = $string =~ m{(a=\d+)}g; for (@list) { print "$_\n"; }
      Minor Nitpick:

      Why bother with the redundent @list?

      $string = 'a=111a=222a=333'; for ($string =~ m/(a=\d+)/g) { print "$_\n"; # any other code }

        For that matter, if you are grouping all the matches at once, why bother with the temporary string?

        for ($obj->method =~ /pat(keep)/g) { print $count++, " $_\n"; # etc. }


Re: Infinite loop regex
by broquaint (Abbot) on Aug 04, 2002 at 11:45 UTC
    You probably want to use the \G anchor e.g
    print "[$1]" while "foo bar baz quux" =~ /\G(\w+) ?/g; __output__ [foo][bar][baz][quux]
    See the perlre manpage for more info.


Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://187433]
Approved by MrNobo1024
Front-paged by andye
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2021-10-26 01:43 GMT
Find Nodes?
    Voting Booth?
    My first memorable Perl project was:

    Results (90 votes). Check out past polls.