http://www.perlmonks.org?node_id=1056009

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

I am writing a program to rename variables in VB code. I generate a hash of new names keyed by the current names. I want to replace all instances of the old name by the new name except where they appear in strings or comments.

Some notes on VB:

The program builds up the list of renames as is reads the code line by line. The renames are performed on each line after it is processed. Is there a better way to perform the renaming?

use strict; use warnings; my $renames = { this_sub => 'that_sub', var_1 => 'var_a', var_2 => 'var_b', Ignore => 'FAILED', nothing => 'FAILED', and => 'FILED', can => 'FAILED', t => 'FAILED', do => 'FAILED', it => 'FAILED', }; my $line = qq/ this_sub("first", var_1, "Ignore ""can't""", var_2) ' + do it\n/; print $line; my $matched_keys = '\b' . join( '|', keys %$renames ) . '\b'; my $match = qr/($matched_keys)/; my $vb_string = qr/("[^"]*(?:""[^"]*)*")/; my @parts = split $vb_string, $line; my $do_code = 0; for my $part (@parts) { $do_code = !$do_code; next unless $do_code; if ( $part =~ m/'/ ) { my ( $code, $comment ) = split /'/, $part, 2; $code =~ s/$match/$renames->{$1}/ge; $part = "$code'$comment"; last; } else { $part =~ s/$match/$renames->{$1}/ge; } } print join( "", @parts )
Output:
this_sub("first", var_1, "Ignore ""can't""", var_2) ' do it that_sub("first", var_a, "Ignore ""can't""", var_b) ' do it

Replies are listed 'Best First'.
Re: Replacing words in VB code but not strings or comments
by AnomalousMonk (Archbishop) on Sep 27, 2013 at 20:49 UTC

    Here's an approach that works for 5.14+. (Still working on something for earlier versions.) I would add some more test cases. (BTW: I'm not familiar with VB, so I'm just going by what you have described of the syntax.)

    Output:

    c:\@Work\Perl\monks\Anonymous Monk\1056009>perl parse_and_sub_vb_2.pl # # testing function replace_5_14() # ok 1 ok 2 ok 3 ok 4 ok 5 ok 6 ok 7 ok 8 - no warnings 1..8
      That is the kind of solution I was looking for. Unfortunately I am targeting 5.8.8, the version installed by the vendor of the I am supporting. Thank you for you effort.
Re: Replacing words in VB code but not strings or comments (5.8/10 versions)
by AnomalousMonk (Archbishop) on Sep 28, 2013 at 02:30 UTC

    Following tested under ActiveState 5.8.9 and Strawberries 5.10.1.5, 5.12.3.0 and 5.14.4.1. I'm sure this code can be simplified a bit. No Benchmark-ing whatsoever done.

Re: Replacing words in VB code but not strings or comments (Simplified versions)
by AnomalousMonk (Archbishop) on Sep 28, 2013 at 19:45 UTC

    Here's a variation for 5.8 and also for 5.10 that's simpler (for some definition of 'simpler') and that I think should run faster since it avoids  /e code evaluation during replacement, but again, I've done no benchmarking. Of course, the same approach applies as well to the 5.14 version code. Tested with the same Perl versions/vendors as before. Also to repeat: adding more of your own test cases would probably be a good idea.