in reply to Parse File With Sub While Loops

You may be able to do this very easily with the range operator.
while (<MYFILE>) { if (/^FH$/ .. /^FT$/) { # $_ is a line within FH and FT lines # including the delimiting lines } if (/^BH$/ ... /^BH$|^FT$/) { # $_ is a line between BH lines, or between # a BH and FT line }
Basically, the first if is true only if we've already found a line containing only FH, but haven't yet found a line containing FT. The second if is true when we've found a BH line, but haven't yet found either another BH line or an FT line.

Hope this helps,
-- Bird

Oh, the reason the second if uses three dots (...) is because the two dot version can become false in the same check that it became true. Essentially, if you use the two dot version to match a block which uses the same start and end delimiter, you may only end up processing the first line of the block (which would be the delimiter, in this case).

Replies are listed 'Best First'.
Re: Re: Parse File With Sub While Loops
by bronto (Priest) on Sep 17, 2002 at 10:46 UTC

    Oh, my God!

    Bird, your node shows me the light on the range operator, which I didn't know in it's full power!

    I think that the information you linked is worth to be read immediately, so I paste it here:

    In scalar context, ".." returns a boolean value. The operator is bistable, like a flip-flop, and emulates the line-range (comma) operator of sed, awk, and various editors. 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. It doesn't become false till the next time the range operator is evaluated. It can test the right operand and become false on the same evaluation it became true (as in awk), but it still returns true once. If you don't want it to test the right operand till the next evaluation, as in sed, just use three dots ("...") instead of two. In all other regards, "..." behaves just like ".." does.

    The right operand is not evaluated while the operator is in the "false" state, and the left operand is not evaluated while the operator is in the "true" state. The precedence is a little lower than || and &&. The value returned is either the empty string for false, or a sequence number (beginning with 1) for true. The sequence number is reset for each range encountered. The final sequence number in a range has the string "E0" appended to it, which doesn't affect its numeric value, but gives you something to search for if you want to exclude the endpoint. You can exclude the beginning point by waiting for the sequence number to be greater than 1. If either operand of scalar ".." is a constant expression, that operand is implicitly compared to the $. variable, the current line number.

    Ciao!
    --bronto

    # Another Perl edition of a song:
    # The End, by The Beatles
    END {
      $you->take($love) eq $you->made($love) ;
    }