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


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

Replying to myself, here is a corrected and simplified version:

#!/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; eval "\$line =~ s{\$query}{$replace}g;"; die $@ if $@; 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$
  • Comment on Re^2: Evaluating user-entered captured groups during Perl substitution
  • Download Code

Replies are listed 'Best First'.
Re^3: Evaluating user-entered captured groups during Perl substitution
by Polyglot (Chaplain) on Mar 16, 2020 at 19:50 UTC

    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~

      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$