use warnings; use strict; use autodie; use Data::Dump qw(dd); use constant TRIGGER => qr{ \b bar \b }xms; # arms a reference number MAIN: { # all lexical variables within this scope are isolated die "usage: $0 " unless @ARGV == 1; # slurp entire file to memory. my $filename = $ARGV[0]; my $allfile = do { local $/; open my $fh_in, '<', $filename; <$fh_in>; }; # capture list of ref object numbers to delete. my @object_numbers = do { # all these substrings appear alone on a line. my $rx_blk_start = qr{ ^ begin $ }xms; # block start my $rx_ref_n = qr{ ^ \d+ $ }xms; # ref number my $rx_blk_end = qr{ ^ end $ }xms; # block end # this matches any stuff before end of block. my $rx_not_blk_end = qr{ (?! $rx_blk_end) . }xms; # return list of captures. $allfile =~ m{ $rx_blk_start \n ($rx_ref_n) \n # capture valid ref number for deletion $rx_not_blk_end* # any stuff before block end ${ \TRIGGER } # must appear at least once in block $rx_not_blk_end* # any stuff before block end $rx_blk_end }xmsg; }; # dd 'object_numbers', \@object_numbers; # FOR DEBUG # build regex of ref object numbers to delete. my ($rx_del_ref_n) = map qr{ \b (?: $_) \b }xms, join '|', reverse sort @object_numbers ; # print 'delete ref n regex', $rx_del_ref_n, "\n"; # FOR DEBUG # delete all ref n objects from text. $allfile =~ s{ ^ (?: [ ]* foo)? [ ]+ ref [ ] $rx_del_ref_n \n } {}xmsgo; # print "edited allfile [[$allfile]] \n"; # FOR DEBUG # save processed file to new file. my $out_filename = "$filename.removed"; open my $fh_out, '>', $out_filename; print $fh_out $allfile; close $fh_out; exit; } # end MAIN block die "unexpected exit from MAIN";