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

How can I match only the warn within the loop ... endloop;
begin loop warn('xxx'); endloop; loop null; endloop; begin warn('yyy'); end; warn('zzz'); end;

Replies are listed 'Best First'.
Re: regex help ...
by Roger (Parson) on Nov 25, 2003 at 11:07 UTC
    How about this attempt?
    #!/usr/local/bin/perl -w use strict; my $file; { local $/; $file = <DATA>; } print "$_\n" for $file =~ m/loop\s*(warn.*)\s*endloop/mg; __DATA__ begin loop warn('xxx'); endloop; loop null; endloop; loop warn('rrr'); endloop; begin warn('yyy'); end; warn('zzz'); end;
    And the output is -
    warn('xxx'); warn('rrr');
Re: regex help ...
by dragonchild (Archbishop) on Nov 25, 2003 at 12:56 UTC
    You might want to look at Parse::RecDescent if you're going to do more than just check the warn within loop...endloop. It will handle the annoying parsing bits and do it right. (Not to say that you won't ... just that I wouldn't want to even try when other options exist.)

    ------
    We are the carpenters and bricklayers of the Information Age.

    The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

    ... strings and arrays will suffice. As they are easily available as native data types in any sane language, ... - blokhead, speaking on evolutionary algorithms

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: regex help ...
by delirium (Chaplain) on Nov 25, 2003 at 10:59 UTC
    perl -lne '$flag=1 if /loop/;$flag=0 if /endloop/; print if /warn/ && $flag' file.txt

      Pardon me if I say ick! Every time I see "flag variables" I cringe. That could be written better (IMHO) like so: perl -ne 'next unless /loop/../endloop/; print if /warn/;' file.txt

        or just
        perl -ne 'print if /loop/../endloop/ and /warn/' file.txt

        The PerlMonk tr/// Advocate
        Nice.

        From perlop:

        Each ".." operator maintains its own boolean state. It is false as long as its left operand is false. Once the left operand is true, the range operator stays true until the right operand is true, AFTER which the range operator becomes false again.

        I had no idea about this before I saw your post. That will clean up many of my scripts quite a bit. Thanks for pointing that out.