our %ESCAPES = (
n => "\n",
t => "\t",
);
my $interpolated = '';
{
local *_ = \$string; # Alias $_ to $string.
for (;;) {
if (/\G \$(\w+) /gcsx || /\G \${(\w+)} /gcsx) {
$interpolated .= eval '$'.$1;
next;
}
if (/\G \\(.) /gcsx) {
$interpolated .= exists($ESCAPES{$1}) ? $ESCAPES{$1} : $1;
next;
}
/\G
(
. # Catchall.
(?: # These four lines are optional.
(?!\\) # They are here to speed things up
(?!\$) # by avoiding adding individual
.)* # characters to the $interpolated.
)
/gcsx && do { $interpolated .= $1; next; };
last;
}
}
####
our %ESCAPES = (
n => "\n",
t => "\t",
);
sub interpolate {
local *_ = \$_[0]; # Alias $_ to $_[0].
my $interpolated = '';
for (;;) {
if (/\G \$(\w+) /gcsx || /\G \${(\w+)} /gcsx) {
no strict 'refs';
#no warnings;
$interpolated .= ${$1};
next;
}
if (/\G \\(.) /gcsx) {
$interpolated .= exists($ESCAPES{$1}) ? $ESCAPES{$1} : $1;
next;
}
/\G
(
. # Catchall.
(?: # These four lines are optional.
(?!\\) # They are here to speed things up
(?!\$) # by avoiding adding individual
.)* # characters to the $interpolated.
)
/gcsx && do { $interpolated .= $1; next; };
last;
}
return $interpolated;
}
####
our %ESCAPES = (
n => "\n",
t => "\t",
);
sub interpolate {
local *_ = \$_[0]; # Alias $_ to $_[0].
my $symtab = $_[1];
my $interpolated = '';
for (;;) {
if (/\G \$(\w+) /gcsx || /\G \${(\w+)} /gcsx) {
if (!exists($symtab->{$1})) {
$interpolated .= "[unknown symbol \$$1]";
} elsif (!defined($symtab->{$1})) {
$interpolated .= "[undefined symbol \$$1]";
} else {
$interpolated .= $symtab->{$1};
}
next;
}
if (/\G \\(.) /gcsx) {
$interpolated .= exists($ESCAPES{$1}) ? $ESCAPES{$1} : $1;
next;
}
/\G
(
. # Catchall.
(?: # These four lines are optional.
(?!\\) # They are here to speed things up
(?!\$) # by avoiding adding individual
.)* # characters to the $interpolated.
)
/gcsx && do { $interpolated .= $1; next; };
last;
}
return $interpolated;
}
my %symtab = (
string => "cheese",
#user => $user,
#...
);
my $need_to_interpolate = 'smell my $string\n';
print interpolate($need_to_interpolate, \%symtab);