The following code snippet works fine with Perl (v5.16.2). However, when I run it with Perl v5.8.9, it complains about the following regular expression. How can I rewrite this regex like it does with Perl v5.8.9. (I can not update the version).
REGEX:
use strict; use warnings; our %formula_per_k; INIT { # List all functions that you want to allow in formulas. All other words will be interpretted as variables. my @FORMULA_FUNCS = qw(sqrt exp log); # Load the data via a file. my $data = do {local $/; <DATA>}; # Parse K blocks while ($data =~ m{ ^K \s+ (\w+) \s* \{ ( (?: [^{}]+ | \{(?2)\} )* ) # Matched braces only. \} }mgx) { my ($name, $params) = ($1, $2); # Parse LOL block next if $params !~ m{ LOL \s* \{ ( (?: [^{}]+ | \{(?1)\} )*? ) # Matched braces only. \} }mx; my $lol = $1; # Start building anonymous subroutine my $conditions = ''; # Parse Conditions and Formulas while ($lol =~ m{ COND \s* \{ (.*?) \} \s* FORMULA \s* \{ (.*?) \} }gx) { my ($cond, $formula) = ($1, $2); # Remove Excess spacing and translate variable into perl scalar. for ($cond, $formula) { s/^\s+|\s+$//g; s{([a-zA-Z]+)}{ my $var = $1; $var = "\$hashref->{$var}" if ! grep {$var eq $_} @FORMULA_FUNCS; $var }eg; } $conditions .= "return $formula if $cond; "; } my $code = "sub {my \$hashref = shift; ${conditions} return; }"; my $sub = eval $code; if ( $@ ) { die "Invalid formulas in $name: $@ "; } $formula_per_k{$name} = $sub; } } sub formula_per_k { my ($k, $vars) = @_; die "Unrecognized K value '$k'" if ! exists $formula_per_k{$k}; return $formula_per_k{$k}($vars); } print "'K1', {d => .1} = " . formula_per_k('K1', {d => .1}) . "\n"; print "'K1', {d => .05} = " . formula_per_k('K1', {d => .05}) . "\n"; print "'K3', {d => .02} = " . formula_per_k('K3', {d => .02}) . "\n"; print "'K3', {d => .021} = " . formula_per_k('K3', {d => .021}) . "\n"; __DATA__ ... #OTHER STUFFS K K1 { LOL { COND { d < 0.01 } FORMULA { -0.2 + 3.3*sqrt(d) } COND { d >= 0.01 } FORMULA { -0.2 + 3.3*sqrt(d+0.4) } } } ... #OTHER STUFFS K K2 { LOL { COND { d < 0.03 } FORMULA { -2.2 + 1.3*sqrt(d) } COND { d >= 0.03 } FORMULA { -2.2 + 1.3*sqrt(d+0.8) } } } ... #OTHER STUFFS K K3 { LOL { COND { d < 0.02 } FORMULA { -4.3 + 0.3*sqrt(d) } COND { d >= 0.02 } FORMULA { -4.3 + 0.3*sqrt(d+0.3) } } } ... #OTHER STUFF
Outputs:
'K1', {d => .1} = 2.13345237791561 'K1', {d => .05} = 2.01370729772479 'K3', {d => .02} = -4.13029437251523 'K3', {d => .021} = -4.13002941430942
Error:
Sequence (?1...) not recognized in regex; marked by <-- HERE in m/ ^K \s+ M3 \s* { ( (?: [^{}]+ | {(?2 <-- HERE )} )* ) # Matched braces only. } / at ./code.pl line 215, <RFILE> line 12.
UPDATE: The code is updated. This was originally proposed by https://stackoverflow.com/users/1733163/miller
user1709175
source share