3

So I tested out a regular expression that utilizes the experimental embedded code features. My tests worked, so I expounded upon it to do a more sophisticated script, but ran into errors. I traced the errors to a simple use of a variable in the regular expression not in the embedded code. I tried doing the regex in the suggested eval, but discovered that that wouldn't work because I could not access special variables after the eval'ed regular expression. I eventually re-wrote the code to not use the embedded code strategy, but am left curious as to why it wouldn't work. I simplified the problem in a pair of perl one-liners below:

This works:

perl -e '$_ = "The brown fox jumps over the lazy dog ABC god yzal eht revo spmuj xof nworb ehT";
    while (/(.{10,41})(?{$cap = $^N;$rev = r($cap);})(...)(??{$rev})/ig {
        print("$1\n")
    }
    sub r { return(join("",reverse(split("",$_[0])))) }'

So why doesn't this?:

perl -e '$_ = "The brown fox jumps over the lazy dog ABC god yzal eht revo spmuj xof nworb ehT";
    $f=10;
    $e=41;
    while (/(.{$f,$e})(?{$cap = $^N;$rev = r($cap);})(...)(??{$rev})/ig) {
        print("$1\n")
    }
    sub r { return(join("",reverse(split("",$_[0])))) }'

The error I get is:

Eval-group not allowed at runtime, use re 'eval' in regex 
m/(.{10,41})(?{$cap = $^N;$rev = r($cap);})(...)(??{$rev})/ at -e line 1.

Is there a way to make it work with the $f and $e variables - a way that allows me to use the special variables

$`, $&, $', and @- 

afterwards? Do I need to use eval?

Thanks, Rob

2
  • One question that comes to mind is why do you have a subroutine that does exactly what reverse does in scalar context? $rev = reverse($^N) is all you need. – TLP May 1 '13 at 15:13
  • Yes. I do know that, but thanks for pointing it out. I originally had the code you suggested, but as I mentioned, I was testing for some more sophisticated code and I wanted to call a sub in the subsequent version that did something else. So that's why I created the useless sub in my test. – hepcat72 May 1 '13 at 19:10
5

You need to use

use re 'eval';

It lets Perl know you are aware that the pattern being interpolated can evaluate arbitrary code and that you're ok with that. It's lexically-scoped, so it will only affect the regular expressions in the file or in the curlies where it is used.

Since you have a one-liner, you can do the same using the command line option

-Mre=eval
3
  • 1
    To my knowledge, use re 'eval'; doesn't affect access to any variable, and your code works fine when I add that line, so you'll have to be clearer about what you mean by "a way that allows me to use the special variables $`, $&, $', and @-". – ikegami May 1 '13 at 15:08
  • 1
    I was wrapping my pattern match in an eval and the resultant values of those variables appeared to be junk. I apparently did not understand that the error was telling me to add the line "use re 'eval'" to my code. I'd thought it was suggesting that I wrap the regex in an eval. – hepcat72 May 1 '13 at 18:22
  • Yes, other than "-Meval=re" should be "-Mre=eval". Thanks! – hepcat72 May 1 '13 at 19:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.