in reply to Re: Global substitution and report
in thread Global substitution and report

No, but the line where the substitution starts would be enough. So going line by line isn't really an option since this would disable multi-line substitutions. Isn't there a cool trick using the e modifier for substitutions?

Replies are listed 'Best First'.
Re^3: Global substitution and report
by moritz (Cardinal) on Aug 27, 2007 at 08:58 UTC
    You could try to push the value of pos onto an array.

    $str =~ s{$pattern}{push @positions, pos $str; $substitution}eg

    I never worked with pos so I don't know if that helps you.

      It is nearly perfect, but
      $wFound = $szText =~ s/$szSearchText/push @wPos, pos $szText;$szReplac +eText/eg; foreach my $Line (@wLines) { $wLine = Convert::posToLine($szText, $Line); if ($wLines[-1] != $wLine) { push @wLines, $wLine; } print "Line: $wLine\n"; }
      doesn't replace correct if the replacement is something like "\L$1\E".
        There are two possible workarounds:

        A string eval, e.g.

        my $subst = 'lc $1'; # and later $str =~ s{$pattern}{push @pos, pos $str; eval $subst; }eg

        The other one moves the push to the regex:

        use strict; use warnings; use Data::Dumper; my @pos; my $str = "foobarbaz"; if ($str =~ s{([aeiou]+)(?{ push @pos, pos $str })}{<--$1-->}g){ print Dumper \@pos; print $str, "\n"; }

        But please read the notes in perlre on the (?{...}) construct.

Re^3: Global substitution and report
by Anno (Deacon) on Aug 27, 2007 at 09:22 UTC
    How do you expect /e could help? It only changes the behavior of the substitution side of s///.

    One possibility is to step through substrings of the file content, starting at each new line. Here is a sketch:

    my $content = do { local $/; <DATA> }; my ( $ln, $start) = ( 1, 0); while ( $start < length $content ) { if ( substr( $content, $start) =~ s/.../.../ ) { print "line $ln changed\n"; } $start = 1 + index( $content, "\n", $start); ++ $ln; } __DATA__ aaa bbb ccc ddd eee
    Anno