in reply to Re: Efficient method to replace middle lines only when no match
in thread Efficient method to replace middle lines only when no match

Thanks for using \K in your post, it made me think a bit more and I came up with a solution that doesn't have a penalty when there's a negative match:

# slow no longer my $has_field2 = "field1: valueA\nfield2: valueB\nfield3: valueC\n"; $has_field2 .= "........................................\n" x 1000; $has_field2 =~ s/field1:[\n]*\n\K(?!field2:).*(?=\nfield3:) /field2: valueB /msx;

Also, I didn't edit my original post.

Replies are listed 'Best First'.
Re^3: Efficient method to replace middle lines only when no match
by AnomalousMonk (Archbishop) on Mar 20, 2014 at 15:49 UTC
    $has_field2 =~ s/field1:[\n]*\n\K(?!field2:).*(?=\nfield3:) /field2: valueB /msx;

    1. Shouldn't the  [\n]*\n after  field1: in the search pattern be  [^\n]*\n (negated class) instead?
    2. The  .* in the search pattern is greedy. Your test string has only one occurrence of the  "field1: valueA\nfield2: valueB\nfield3: valueC\n" substring. What happens if you test against many occurrences (see below — BTW, I have an updated version of this script that, among other things, uses hi-res timing if you're interested)? Won't the greedy  .* just gobble all intervening occurrences?
    3. You have a newline and a lot of blank space in your replacement string; is this what you want?
      c:\@Work\Perl\monks\Zu>perl -wMstrict -le "my $s = 'xxxyxxx'; $s =~ s/y /FOO /xms; print qq{'$s'}; " 'xxxFOO xxx'