$phrase = 'Hello $dolly!';
$variables = { dolly => 'Nurse' };
####
$phrase =~ s/\$([a-zA-Z0-9_]+)/$variables->{$1}/g;
# also process variables in $(var_name) format.
$phrase =~ s/\$\(([a-zA-Z0-9_]+)\)/$variables->{$1}/g;
##
##
$phrase = '$foo $bar';
$variables = { foo => '$(bar)', bar => '$(foo)', };
##
##
my @phrase_parts = split /(\$(?:\(\w+\)|\w+))/, $phrase;
foreach my $part ( @phrase_parts ) {
$part =~ s{ \$ (\w+) }{$variables->{$1}}xms
|| $part =~ s{ \$ \( (\w+) \) }{$variables->{$1}}xms;
}
$phrase = join '', @phrase_parts;