Another way. I've "corrected" all the presumably incorrect 't13:45\n' lines to "t13:45\n" (single-quotes to double quotes so the \n escape means something) and added a blank line to section output for looks.
use strict;
use warnings;
my @lines = (
"t13:45\n", "D13:45\n", "S13:45 Unicorn\n", "D13:45\n", "S13:45\n"
+, "T13:45\n",
"t13:45\n", "D13:45\n", "T13:46\n",
"t13:45\n", "D13:45\n", "S13:45\n","D13:45\n", "S13:45 UNICORN\n",
+ "T13:45\n",
"t13:45\n", "D13:45\n", "T13:46\n",
);
use constant GOOD_LINE => qr{ \A [tTJSD] }xms;
use constant END_SECTION => qr{ \A T }xms;
my $value = "uNiCoRn";
my @section;
LINE:
while (my $line = shift @lines) {
die "bad line '$line'" unless $line =~ GOOD_LINE;
push @section, $line;
next LINE unless $line =~ END_SECTION;
if (grep m{ (?i) \Q$value\E }xms, @section) {
print for @section;
print "\n";
}
@section = ();
}
__END__
t13:45
D13:45
S13:45 Unicorn
D13:45
S13:45
T13:45
t13:45
D13:45
S13:45
D13:45
S13:45 UNICORN
T13:45
The
grep in the section-printing conditional at the end of the loop is a little wasteful because it will continue matching after a match is found. See
List::Util::any() for an alternative that may be better (because it short-circuits) if the number of lines in a section is very large or matching is very expensive.
Update: It occurs to me that you may want a strict ordering of section markers so that a 't...' line only occurs at the start of a section. If that's the case, define a section start regex
use constant START_SECTION => qr{ \A t }xms;
and add this die statement
die "start line '$line' not at start of section"
if $line =~ START_SECTION and @section;
just before the
push @section, $line;
statement. That oughta fix it. (Update: And if you want a really strict strict ordering, let me know; can do, will do.)
Give a man a fish: <%-{-{-{-<