in reply to Function call in regex replacement string

I'm not sure exactly what you want, but you should be able to do it with the /e modifier. At the beginning of your script you have something like this:
my $replacement = sub { return unpack("a1", shift); };
and then later
for (@array) { s/HAI WORLD Times ([0-9]+).*/ '\t\t<exML LOLZ = "' . $replacement->($1) . '"/>' /eg; }

Replies are listed 'Best First'.
Re^2: Function call in regex replacement string
by PoorLuzer (Beadle) on Feb 24, 2009 at 09:28 UTC
    :-)

    Yes.. I thought about both the /e and eval ( :-o ) approaches, but they do not satisfy my needs... let me try and clarify:

    I want to provide the replacement string as a configurable parameter and not embedded within the search - replace code.

    I would like to have :
    for (@array) { s/HAI WORLD Times ([0-9]+).*/ '\t\t<exML LOLZ = "' . $replacement->($1) . '"/>' /eg; }

    as
    for (@array) { s/$searchString/$replaceString/g; }


    Um.. does that make sense?
      What you're asking for won't work without a bunch of magic. If you really, really want it to look like that, create an object with an overload that causes it to do something particular when you stringify it. If you do that, though, then don't blame me if the maintenance programmer turns out to be a psychopath with an axe who knows where you live.

      However the following can work and at least gives a hint as to the evil lurking within:

      for (@array) { s/$searchString/$replaceString/eeg; }
      Where the ee means you eval it, and then eval the result of that. Or in other words you execute whatever is in $replaceString as code. I would set that up more sanely as:
      for (@array) { s/$searchString/$replace->()/eg; }
      But then again I'm a sane sort of guy who doesn't want to worry about maintenance programmers on a vendetta.
        Hi tilly,

        My requirement is exactly what the attached program behaves like - only thing I did not want to use in my program was eval.

        In the end, unfortunately, eval seems the only way out. I did not want it to be (I pointed out in the very beginning that eval would work but was not preferred).

        Maintainance would be an issue, but then this approach would do away with people grepping through the source and locate the replacement expressions .. how useful is that too from the maintainance point of view?

        With the horrific approach below, you can very well put the replacement string in an external config file and keep such things separate from the main program... in my view that is more maintainable... would you (or anyone else) not agree?

        Why would anyone keep configurable things embedded in the logic/source code?

        use strict; use warnings; use Data::Dumper; use Tie::File; # open the file if it exists, but fail if it does not exist use Fcntl 'O_RDWR'; our @array = (); our $file = 'hai'; tie @array, 'Tie::File', $file, mode => O_RDWR or die $!; our $SearchString = 'HAI WORLD Times ([0-9]+).*$'; our $ReplaceString = '"\t\t<exML LOLZ = \"" . unpack(\'a1\', $1) . "\" +/>"'; my $elementIdx = 0; while($elementIdx <= $#array) { if($array[$elementIdx] =~ $SearchString) { # Maintain only the first character $array[$elementIdx++] = eval $ReplaceString; } else { splice @array, $elementIdx, 1; # we don't want this in the output } } untie @array; # all done!