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

monks, my goal is to grab a web page, go through the HTML, match something on one line, grab the next five lines including the one that matched and parse those in order to construct and send an email. Grabbing the page, making the match, parsing the results and sending the email I know how to do (or, at least, I have done bfore (; ). My trouble is telling my program to match the one line, and then grab exactly four more, and then stop. I have no code to post as of yet - just playing with pseudo-code so far for this. I was thinking I could set a varible something like a counter, make it true on the first match, and then short circuit the loop when it hits five, but doing that is not happening for me.

am i on the right track? Should I be doing something else here?

-- I'm a solipsist, and so is everyone else. (think about it)

p.s. this is sort of an exercise for me to learn the LWP module and more about regex - I'm sure there are a million modules which would do all this for me, but that wouldn't really teach me a darned thing now would it? :)

Replies are listed 'Best First'.
RE: grabbing N lines after matching one?
by mdillon (Priest) on Sep 16, 2000 at 20:46 UTC
    something like this should do the trick: perl -ne 'print if /match/ .. (++$lines > 4)'
Re: grabbing N lines after matching one?
by cianoz (Friar) on Sep 16, 2000 at 21:21 UTC
    my ($line, $result); while($line = <HTMLFILE>) { if($line =~ /what_you_are_looking_for/) { $result = $line; for(0..3) { $result .= <HTMLFILE>; } last; } }
Re: grabbing N lines after matching one?
by fundflow (Chaplain) on Sep 16, 2000 at 20:48 UTC
    The nicest way to do this in Perl is probably using the .. operator (check the manpage for more variations)

    Something like:
    while(<>) { if (/first-line-pattern/ .. /last-line-pattern/) { do your stuff; } }
RE: grabbing N lines after matching one?
by jptxs (Curate) on Sep 16, 2000 at 20:50 UTC

    couldn't seem to edit my last comment....

    here is what I have so far (first version to make it past -w):

    use strict; use LWP::Simple; use Date::Business; my $content = get("http://quotes.barchart.com/quote.asp?sym=qsft&code= +BGND"); open( FILE, ">stocks.txt" ) or die; print FILE $content; close FILE; my $today = new Date::Business(); my $date = $today->image(); my ($century, $year, $month, $day) = unpack "A2 A2 A2 A2", $date; my $search_date = sprintf "%s/%s/%s", $month, $day, $year; ###testing on a weekend :) $search_date = "09/15/00"; open( STOCK, "stocks.txt" ) or die; my (@lines, $matcher); while ( <STOCK> ) { if ( m/$search_date/ ) { push @lines; if ( $matcher eq "" ) { $matcher = "1"; } else { $matcher++; } } if ( $matcher eq "6" ) { last; } } close STOCK; print "@lines\n\n";

    -- I'm a solipsist, and so is everyone else. (think about it)

      the main problem i see with this code is the following: push @lines; this line does nothing, so the @lines array is always empty whe you attempt to print its contents. what you probably wanted is: push @lines, $_; also, you are testing the equality of a numeric variable against an integer with eq which is the string equality operator, as opposed to == the numeric one.

        bingo :) ...and just the other day my pal was chiding me for not using the default actions enough. I guess I too overzelous with them this time, I thought 'push' would just shove $_ in there lacking any other arguement. RTFM on me :)

        -- I'm a solipsist, and so is everyone else. (think about it)

Re: grabbing N lines after matching one?
by BastardOperator (Monk) on Sep 16, 2000 at 20:55 UTC
    This is completely untested and I'm sure a lot more wordy than it needs to be, but I'm tired and didn't feel especially graceful :^).
    my $cntr = 0 my $stuff = "" LINE: while(<HTMLFILE>) { if($cntr == 0 && $_ !~ /$myregex/) { next LINE; } last LINE if $cntr >= 5; $stuff .= $_; $cntr++; }