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

i have a simple file :
hello world0 hello world1 hello world2 AAAAAA this is a test of the emergency broadcast system BBBBBB hello world0 hello world1 hello world2 AAAAAA if this had been a real emergency more instructions would have followed BBBBBB hello world0 hello world1 hello world2
i am trying to grab the text (running through various lines) within "AAAAAA" and "BBBBBB" i am using the following code:
undef $/;# read in whole file, not just one line or paragraph while ( <> ) { while ( /AAAAAA(.*?)BBBBBB/sgm ) { print "$1\n"; } }
this will only print the first "this is a test of the emergency broadcast system" and not the second one ... there will be several chunks and i would like to print them all out (or save them in an array i can manipulate later) ... how do i do this ???

Replies are listed 'Best First'.
Re: matching several lines
by ikegami (Patriarch) on Feb 05, 2008 at 20:11 UTC

    this will only print the first "this is a test of the emergency broadcast system" and not the second one ..

    No, it prints both.

    undef $/;# read in whole file, not just one line or paragraph while ( <DATA> ) { while ( /AAAAAA(.*?)BBBBBB/sgm ) { print "$1\n"; } } __DATA__ hello world0 hello world1 hello world2 AAAAAA this is a test of the emergency broadcast system BBBBBB hello world0 hello world1 hello world2 AAAAAA if this had been a real emergency more instructions would have followed BBBBBB hello world0 hello world1 hello world2
    this is a test of the emergency broadcast system if this had been a real emergency more instructions would have followed
Re: matching several lines
by Narveson (Chaplain) on Feb 05, 2008 at 18:58 UTC

    Instead of slurping, process one line at a time:

    SKIP: while ( <> ) { next SKIP if !/^AAAAAA/; PRINT: while ( <> ) { last PRINT if /^BBBBBB/; print; } }
Re: matching several lines
by apl (Monsignor) on Feb 05, 2008 at 18:46 UTC
    If you $/ = 'BBBBBB';, then you can loop on if ( /AAAAAA(.*?)$/ ) rather than your inner while.

    Revised Made code a little tighter.

Re: matching several lines
by kyle (Abbot) on Feb 05, 2008 at 19:59 UTC

    This was a more elegant solution before I started testing it. This uses the flip flop operator ("..", see perlop) to detect when it's in the delimiters.

    my $start = qr/A{6}/; my $end = qr/B{6}/; while ( <DATA> ) { if ( m{$start} .. m{$end} ) { next if m{$start}; next if m{$end}; print; } } __DATA__ hello world0 hello world1 hello world2 AAAAAA this is a test of the emergency broadcast system BBBBBB hello world0 hello world1 hello world2 AAAAAA if this had been a real emergency more instructions would have followed BBBBBB hello world0 hello world1 hello world2 __END__ this is a test of the emergency broadcast system if this had been a real emergency more instructions would have followed

    This doesn't produce the blank lines between the text sections like the original one does, but it pulls out the desired text clearly enough. If the blank lines are important, you could do that near one of the nexts.

Re: matching several lines
by Narveson (Chaplain) on Feb 05, 2008 at 18:49 UTC

    Capture the results of the match in an array.

    my @messages = /AAAAAA(.*?)BBBBBB/sgm; foreach (@messages) { print "$_\n"; }
Re: matching several lines
by Erez (Priest) on Feb 06, 2008 at 14:46 UTC