http://qs321.pair.com?node_id=11114361


in reply to Re^2: Evaluating user-entered captured groups during Perl substitution
in thread [SOLVED] Evaluating user-entered captured groups during Perl substitution

Wow! This works!

I actually tried "correcting" what you had there, thinking you'd made a mistake, as it was so simple, i.e., it appeared you'd forgotten the "->()" after "$replace" and the "e" at the end. (I guess I was making this all harder than it needed to be.) Of course, my corrections did not work. Then I took a closer look and realized you had eliminated those evaluated subroutines altogether. I felt like it couldn't possibly work that way, but, went ahead and tried it anyhow. I'm very surprised at how well it works, and I'm not sure why it does work so well. I guess I need to learn more about using eval as a wrapper around a substitution regex. It's highly likely this would have been useful for me in a number of my past projects.

Thank you ever so much for taking time to offer your corrections.

It may be worthy of mention that in my actual code, I am not using any of the quotes such as the qr'(St\.\s)(Mt\.\s)(?=Helens)'; because the variables are coming in straight from the form, with the exception of the untainting routine that the substitution side passes through. So escaped characters were never a part of my issue. The difficulty seems to have been with the complexity of the nested eval.

Blessings,

~Polyglot~

Replies are listed 'Best First'.
Re^4: Evaluating user-entered captured groups during Perl substitution
by jo37 (Deacon) on May 14, 2020 at 16:40 UTC

    Hello Polyglot!

    My approach with eval'ing the complete substitution statement was kind of "brute force".

    I thought about this every now and then and felt dissatisfied with my solution. Now I may round this off with the following:

    #!/usr/bin/perl use Test2::V0; #FROM DATABASE TEXT my $line = "Her house is on 34th Mt. Whitney St. near St. Mt. Helens S +t."; #FROM INCOMING FORM INPUTS my $query = qr'(St\.\s)(Mt\.\s)(?=Helens)'; my $substitution = 'Mount ${1}'; # USER MAY HAVE ENTERED "$1" #FOR RETURNED HTML HIGHLIGHT OF CHANGES my $start = '<span class="highlight">'; my $end = '</span>'; my $replace = $start . $substitution . $end; # twofold quoting and double eval'ing does the trick: $line =~ s{$query}{"qq{$replace}"}gee; is $line, 'Her house is on 34th Mt. Whitney St. near <span class="high +light">Mount St. </span>Helens St.', 'pattern substitution'; done_testing;

    Greetings,
    -jo

    $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$