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

Hello Monks,

when using the /s option modifier in regular expressions, the "." matches also a newline character. Suppose I want to remove the __END__ marker and all following lines from a file. I came up with this code:
use strict; use warnings; my $file = shift; # file to process is the 1st command line argument open my $fh, $file or die; $_ = join '', <$fh>; # make file's content one (big?) line close $fh; s{__END__.*}{}s; print;
Is there a nicer or more idiomatic way to do this? Thanks.

Have a nice day, j

Replies are listed 'Best First'.
Re: /s option modifier in regex substitution
by choroba (Cardinal) on Apr 23, 2012 at 09:19 UTC
    Why do you need to read the whole file into memory?
    open my $FH, '<', $file or die $!; while (<$FH>) { last if /^__END__\s/; # Update: maybe /\b__END__\b/ or /(?:^|\s)__ +END__(?:\s|$)/) print; }
    Also note that both the solutions incorrectly treat code like
    print " __END__ ";
Re: /s option modifier in regex substitution
by davido (Cardinal) on Apr 23, 2012 at 09:22 UTC

    perl -lni.bak -e '/^__END__$/ && last; print;' filename.pl

    Dave

Re: /s option modifier in regex substitution
by JavaFan (Canon) on Apr 23, 2012 at 11:15 UTC
    Beside the token that marks the start of what you want to delete, you're using no more than two characters, which together form one of the most used regexp idioms, and an often used modifier. All together, you have a trivial regexp, easy to understand, no backtracking required, and one that the optimizer can deal with.

    Why do you think there might be a nicer way?

Re: /s option modifier in regex substitution
by 2teez (Vicar) on Apr 23, 2012 at 09:33 UTC

    You could use this:

    use warnings; use strict; my $file = shift; # file to process is the 1st command line argument open my $fh, $file or die":$!"; while(<$fh>){chomp; last if/__END__/; print $_,$/; } close $fh;
Re: /s option modifier in regex substitution
by Anonymous Monk on Apr 23, 2012 at 09:31 UTC

    Is there a nicer or more idiomatic way to do this? Thanks.

    No , its as straight forward as it gets

    You could write  __END__[.\n]* or the results of  qr/.s/ (which are for perl 5.12  __END__(?s-xim:.)* and for perl 5.14  __END__(?^s:.)* ) but they're still hairy regexes