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

I am using s///eeg but I have to append a } in order to get the eval to work. I could use something cleaner than what follows:
>perl -e "$ab=q({eval { return 1*100 } } iiilll { eval {return 'mark'}}); $ab=~s/\{\s*eval([^\}]+)\}\s*\}/qq($1})/eeg; p +rint $ab; if ($@) {print qq(\nERROR\n$@)};"

Celebrate Intellectual Diversity

Replies are listed 'Best First'.
Re: Cleaner Regex
by jryan (Vicar) on Dec 10, 2003 at 00:08 UTC

    The easy fix is to just simply capture the closing bracket as well:

    $ab=~s/ \{ \s* eval ([^\}]+ \}) \s* \} /$1/egx; # x modifier added for clarity

    However, your code does have other problems. For instance, the inner blocks (the ones in which the eval is located) may contain other statements besides the eval. The eval-block may itself contain inner blocks as well as containing strings that contain brackets. As it stands, all of these cases will cause your regex to fail. Although you may be able to ignore many of them if you are working within a closed system (i.e., you are in control of the input), it seems that you at least need to worry about strings containing brackets. If you do in fact need to worry about parsing full code, then you may want to consider using a full parsing system like Parse::Recdescent.

    For help in dealing with parsing arbitrary code, you can take a look at Parsing with Perl 6. Although the article deals with parsing code using Perl6 regular expressions, it also provides Perl5 equivalant code at the bottom which you can probably make use of.

Re: Cleaner Regex
by diotalevi (Canon) on Dec 09, 2003 at 21:02 UTC
    Your substitution source code mismatched open-parenthese for close-curly-brace.

    Oh I see. You capture everything between eval and the closing brace. Why not start your capture just inside the opening curly-brace?

    eval \s* \{ [^}]* \}
Re: Cleaner Regex
by hardburn (Abbot) on Dec 09, 2003 at 20:56 UTC

    Are you using something other than perl to parse Perl? If so, you must decide if a partial solution is acceptable. Perl has so many edge cases in its syntax that anyone not hacking the internals has little hope of doing parsing it correctly (and the internals people only get it correct because they're the ones that get to define what "correct" is :)

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    : () { :|:& };:

    Note: All code is untested, unless otherwise stated