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

The following code is a quick hack to demo what I need to do. Basically, find a string of text in a file and replace it with the text generated from a function. I do NOT have access to install any modules that are not standard with perl, and trying to get modules installed is like pulling teeth. The following code obviously does not work. Any ideas would be greatly welcome.
#!/usr/bin/perl -w use strict; my $file = "myfile"; open(FILE,$file); foreach (<FILE>) { $_ =~ s/\<REPLACE_TEXT_1\>/&replace_text_1/ if $_ =~ m/\<REPLACE_T +EXT_1\>/; print "$_"; } close(FILE); sub replace_text_1 { #some stuff print "foobar"; #some other stuff }

Replies are listed 'Best First'.
Re: replacing text with a function
by gjb (Vicar) on Jan 14, 2003 at 13:26 UTC

    You want to use the 'e' modifier to the regex: s/something/somefunction(@somearguments)/e which replaces by the result of the code in the replace part which is then considered a Perl expression. (See perlretut or perlre for more info.)

    Hope this helps, -gjb-

      perfect. thanks.

      And no, it is not homework. Unless you count the fact that I am ssh'd into a server at work from my home.
Re: replacing text with a function
by AcidHawk (Vicar) on Jan 14, 2003 at 13:32 UTC

    This works for me because I can then validate what is returned from the function by checking what is in $rep.

    #!/usr/bin/perl -w use strict; my $file = "myfile"; open(FILE,$file); my $rep = &replace_text_1; foreach (<FILE>) { $_ =~ s/\<REPLACE_TEXT_1\>/$rep/ if $_ =~ m/\<REPLACE_TEXT_1\>/; print "$_"; } close(FILE); sub replace_text_1 { #some stuff #print "foobar"; #some other stuff return("foobar"); }

    -----
    Of all the things I've lost in my life, its my mind I miss the most.
Re: replacing text with a function
by pfaut (Priest) on Jan 14, 2003 at 13:31 UTC

    Is this homework? The substitution operator (s///) is documented in perldoc perlop. Look for the option that allows you to specify an executable expression as the replacement string.

    Also, there is no need to look for a match before doing the replacement. Just do the substitution.

    --- print map { my ($m)=1<<hex($_)&11?' ':''; $m.=substr('AHJPacehklnorstu',hex($_),1) } split //,'2fde0abe76c36c914586c';
Re: replacing text with a function
by vek (Prior) on Jan 14, 2003 at 13:45 UTC
    I just wanted to point out that you don't need this matching code if $_ =~ m/\<REPLACE_TEXT_1\>/;. You can just perform the substitution as it will only substitute if <REPLACE_TEXT_1> is found:
    $_ =~ s/<REPLACE_TEXT_1>/$replace_string/;
    -- vek --
Re: replacing text with a function
by dash2 (Hermit) on Jan 14, 2003 at 14:59 UTC
    One small point: if you are doing a lot of different substitutions, you may feel tempted to do something like

    $text =~ s/(\W+)/$1->()/eg; # replace any nonwhitespace characters wit +h the result of a function call

    The danger is that unless you trust the file being fed into the program, someone might feed you a word that called some bad subroutine in your program. Or it might just happen accidentally!

    To make sure this doesn't happen, set up a hash of subroutine references(I think this could be called a "dispatch table"):

    %subs = ( bar => \&bar foo => \&foo do_something => \&do_something ); $text =~ s/(\W+)/$subs{$1}->() if defined $subs{$1}/eg; # only call fr +om a list of specific subroutines

    The $subs{$1}->() is calling the subroutine reference (coderef) defined in the hash, so for example "bar" would be replaced by the result of the "bar" subroutine.

    dave hj~