Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Using a regex capture as part of a varible

by nysus (Parson)
on May 07, 2020 at 14:16 UTC ( #11116543=perlquestion: print w/replies, xml ) Need Help??

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

I'm throwing in the towel in this one. I'm trying to use this Rex sed function.

I want to be able to capture the match on the left and insert it back into the replacement pattern with $1 but nothing I've tried works. I know I'm missing something simple. Here's my latest iteration:

sed qr{("name": "$section",\n.*\n.*)}, '$1' . $json, $groups_file, multiline => TRUE

But this just inserts "$1" into the file before the $json. If I do:

$1$json

The $1 is empty. Presumably because it is replaced with '' during runtime.

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: Using a regex capture as part of a varible
by soonix (Canon) on May 07, 2020 at 15:08 UTC
    Problem is, here, $1 is interpolated at the call to sed. That means: even before it is known if a match will occur and what will be matched. You could patch your copy of Rex::Commands::File to include /e flags for the two s/// operations in sed, but that is most certainly going to break other things.

    In your case, it looks like you don't want to replace, anyway, but to insert. You could try whether turning your search pattern into a lookbehind might work.

      Yes, good insight. It seems I'm using the wrong tool for the job. I've toyed with lookbehinds and never found a good use case that didn't hurt my brain but this seems like the perfect one.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

Re: Using a regex capture as part of a varible
by Fletch (Bishop) on May 07, 2020 at 14:39 UTC

    Never used it but looking at the source I'm not sure that it'll do what you want. Your second argument is getting passed in as $replace into this bit of code:

    else { @content = split( /\n/, cat($file) ); for (@content) { s/$search/$replace/; } }

    You've tried to quote things correctly, but for that to work there'd need to be an /ee modifier on the substitution to get it evaluate the contents of $replace and then replace with what that expanded text contains. Unless there's some new dark magic I'm not aware of for expansions that lets you turn on /ee at a distance I don't think it's capable of what you're trying to do.

    Edit: Aah you've got the multiline option set; the substitution would be the similar s///mgs a few lines earlier but the problem remains the same (it'd need to be s///mgsee to expand $replace and then evaluate the expanded value).

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

      OK, good to know. My brain seems to have lost all knowledge of the 'e' modifier. Tried to get it to work with this simple example:

      my $new = 'blah'; my $string = 'asdfjkjl'; my $find = '(asd)'; my $replace = '$1' . $new; replace ($string, $find, $replace); sub replace { my $string = shift; my $left = shift; my $replace = shift; $string =~ s/$left/$replace/e; print $string; }

      Still prints $1 in the output though. Adding 'ee' throws an error: "Bareword found where operator expected at (eval 1) line 1, near "$1blah"

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

        You need to set up your replacement string correctly. Once that's done it runs fine with the /ee modifier:

        use strict; use warnings; use Test::More tests => 1; my $new = 'blah'; my $string = 'asdfjkjl'; my $find = '(asd)'; my $replace = qq#\${1} . '$new'#; my $result = replace ($string, $find, $replace); is $result, 'asdblahfjkjl'; sub replace { my $string = shift; my $left = shift; my $replace = shift; $string =~ s/$left/$replace/ee; return $string; }
Re: Using a regex capture as part of a varible
by jcb (Parson) on May 07, 2020 at 23:43 UTC

    You will probably get a warning, but there is an outside chance that sed qr{("name": "$section",\n.*\n.*)}, '\\1' . $json, $groups_file, multiline => TRUE might work.

    For compatibility, Perl also recognizes '\N' for one-digit N in regex substitutions if there are sufficient capture groups in the pattern.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11116543]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2022-05-22 23:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you prefer to work remotely?



    Results (81 votes). Check out past polls.

    Notices?