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

I'm trying to exec regexp on directory tree using folowing script, but substitution regexp doesn't allow me to use \1 or $1 as parameter, so following example doesn't work.
#!/usr/bin/perl use warnings; use strict; use File::Find; my $base = "C:\\Projects\\test"; my $ext = qr/.cpp$/; my $regexp = qr/throw "(.+)"/; my $substitute = qq{throw \("$1"\)}; find(\&process, $base); # Collect files matching pre-set extension sub process { /$ext/ or return; my ($line, $file); $file = $File::Find::name; $file =~ s{/}{\\}g; open (IN, '<', $file) or die "Can not open $file: $!"; while (defined($line = <IN>)) { next if $line !~ /$regexp/; chomp $line; print "$file:\n\t$line\n"; $line =~ s/$regexp/$substitute/; print "\t$line\n"; } close(IN); }

Replies are listed 'Best First'.
Re: Execute regexp on directory tree
by Hofmator (Curate) on Dec 12, 2001 at 14:16 UTC

    Your problem lies here: my $substitute = qq{throw \("$1"\)};

    Using qq makes Perl interpolate variables which means that the current value of $1 (at this place undef) is inserted.

    Update:
    Well, typical, sorry, didn't double check what I wrote (and deleted now :). You have to use the following trick to achieve what you want:

    my $substitute = q{qq{throw ("$1")}}; # and later substitute like this $line =~ s/$regex/$substitute/ee;
    The reason for this is that perl is not automatically doing an interpolation on the substitution string you insert. You have to force that by evalutating before substitution.

    -- Hofmator

      I tried to make changes you proposed, but, it didn't work: instead of
      s/throw "[^"]+"/throw ($1)/
      The result semms like using:
      s/throw "[^"]+"/throw (\$1)/
      So no substitution using matched values is performed, I guess I need that substitution regexp operator would evaluate the $substitute, whereas now it doesn't and just replaces using literal value. P.S. Anarion's suggestion also didn't work for me:
      C:\Projects\Config2\9XImage.cpp: throw "Error writing to floppy!"; qq<throw ("$1")>
      Also literal evaluation.
Re: Execute regexp on directory tree
by Anarion (Hermit) on Dec 12, 2001 at 14:41 UTC
    If you want to replace for the content of $1 you must use /ee modifier to the regex.
    $line =~ s/$regexp/$substitute/ee;
    One advice, its better to use a negated character class:
    qr/throw "([^"]+)"/;
    Update I forgot to say that then you have to change the substitution pattern to something to be evaluated:
    my $substitute = q{qq<throw ("$1")>};

    $anarion=\$anarion;

    s==q^QBY_^=,$_^=$[x7,print