Is there a more compact way to get lines of a file that match a regex than the following?

open my $fh, '<', $file or die "Cannot open $file: $!";
 while ( my $line = <$fh> ) {
        next unless $line =~ m/^foo\/([^\/]+\/?)*==/;
        $line =~ s/==$//g;
        $search_result_set{$line} = 1;
  • Can you please explain what you want to accomplish? Do not expect we will put effort to understand your script. – Romeo Ninov Nov 30 '18 at 8:59
  • @RomeoNinov: How is the regex relevant? I was under the impression that it can be more compact in the read line by line part after opening the file – Jim Nov 30 '18 at 9:08
  • @Inian: Same comment as above – Jim Nov 30 '18 at 9:08
  • @RomeoNinov: E.g. I think there is something like slurp but that is considered insecure or something? – Jim Nov 30 '18 at 9:09
  • 1
    s{^(foo/[^/]+/?)==\s*$}{$1} && $sr{$_}++ while <$fh>; in any case, do not write /..\/..\/../ in perl, ever; write m{.../...} or m#../..# instead. – mosvy Nov 30 '18 at 9:31
 @lines = grep s{^foo/([^/]+/?)*\K==\n?\z}{}, <$fh>;

Would store in the @lines array the lines that match the pattern with a trailing ==\n removed. $ matches both at the end of the subject and before a trailing \n in the subject, here we're using \n?\z (an optional \n followed by the end of the subject (\z)) for that newline to be removed if present, effectively doing chomp's job. \K marks the start of the portion to be substituted.

  • So what about the removal part of the second regex? Should I go over the @lines a second time? – Jim Nov 30 '18 at 9:19
  • @Jim, I missed that part of the requirement. Then, it's even simpler. See edit. – Stéphane Chazelas Nov 30 '18 at 10:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.