Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re: Global substitution and report

by Anno (Deacon)
on Aug 27, 2007 at 08:33 UTC ( [id://635239]=note: print w/replies, xml ) Need Help??


in reply to Global substitution and report

You can use while ( s///g ) safely (note the /g modifier). In scalar context, s///g will restart matching where the last match left off, so no infinite loop. However, tracing lines and particularly line numbers will be hard.

Since you mention changed lines and line numbers it appears that you expect changes to be limited to single lines, as opposed to changes spanning multiple lines. If so, you'd be much better off looping over the file line by line and logging changes as they happen. Note the $. variable, which will give you the line number.

Anno

Replies are listed 'Best First'.
Re^2: Global substitution and report
by Outaspace (Scribe) on Aug 27, 2007 at 08:43 UTC
    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?
      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".
      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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://635239]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2024-04-19 02:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found