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

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

I'm manually interpolating values from a hash ref of internal "environment variables" into a user-supplied string. The string's magic interpolation character is '%', not '$', so "%FOO" in the string should be replaced with the value of $env->{'FOO'}, and "%{BAR}' should be replaced with $env->{'BAR'}, etc. Plus, the interpolation is recursive; if the interpolated value itself contains a '%', it gets re-expanded. Lastly, '%%' eventually gets replaced with a single '%', although this happens later, so I actually need to pass through %-pairs unchanged.

Hope I explained that clearly...

Anyway, the following code snippet does all of this the way I want:
# % expansion. %% gets converted to % later, so expand any # %keyword construction that doesn't have a % in front of it # (modulo multiple %% pairs in between). while (($str =~ s/(^|[^\%](?:\%\%)*)\%([_a-zA-Z]\w*)/"$1".$env->{$2}/g +e) || ($str =~ s/(^|[^\%](?:\%\%)*)\%\{([_a-zA-Z]\w*)\}/"$1".$env->{$ +2}/ge)) {}
But I'm doing this with two very similar expressions, the first for normal unadorned variable names ("%FOO") and the second for variable names enclosed in braces ("%{FOO}"). Can anyone suggest how these two might be combined, hopefully in a way that speeds up the processing? The obvious technique of sticking '*' after the braces in the regexes loses because I don't want to match unbalanced braces like "%FOO}".

I've been leafing through "Mastering Regular Expressions" in search of an answer, especially the section on lookahead, but that's right about where my brain starts filling up...