After numerous heated debates on comp.lang.perl.* here is my new
improved answer for perlfaq4: expanding variables in strings.
--- perlfaq4.pod Thu Mar 6 18:03:55 2003
+++ perlfaq4-bam.pod Thu Mar 6 18:28:36 2003
@@ -539,6 +539,9 @@
This won't expand C<"\n"> or C<"\t"> or any other special escapes.
+See also ``How can I expand/interpolate variables in text strings?'' in this
+section of the FAQ.
+
=head2 How do I remove consecutive pairs of characters?
To turn C<"abbcccd"> into C<"abccd">:
@@ -565,7 +568,7 @@
Version 5.004 of Perl had a bug that gave list context to the
expression in C<${...}>, but this is fixed in version 5.005.
-See also ``How can I expand variables in text strings?'' in this
+See also ``How can I expand/interpolate variables in text strings?'' in this
section of the FAQ.
=head2 How do I find matching/nesting anything?
@@ -898,25 +901,26 @@
If Text::Soundex does not do what you are looking for, you might want
to consider the String::Approx module available at CPAN.
-=head2 How can I expand variables in text strings?
-
-Let's assume that you have a string like:
+=head2 How can I expand/interpolate variables in text strings?
- $text = 'this has a $foo in it and a $bar';
+ $text = 'this has a $foo in it...\n ...and a $bar';
+ # Assume $text does not contain "\nEND\n"
+ chop ( $text = chop "<<END\n$text\nEND\n" );
+ die if $@;
-If those were both global variables, then this would
-suffice:
+This is dangerous if the text comes form an untrusted source,
+consider:
- $text =~ s/\$(\w+)/${$1}/g; # no /e needed
+ $text = '@{[ system "rm -rf /" ]}';
-But since they are probably lexicals, or at least, they could
-be, you'd have to do this:
+If you only need to process simple scalars then you can do limit the
+parts of the string that are passed to eval() like this:
$text =~ s/(\$\w+)/$1/eeg;
die if $@; # needed /ee, not /e
-It's probably better in the general case to treat those
-variables as entries in some special hash. For example:
+This still gives unrestricted access to your scalar variables. It is
+often better to use a hash:
%user_defs = (
foo => 23,
@@ -924,8 +928,8 @@
);
$text =~ s/\$(\w+)/$user_defs{$1}/g;
-See also ``How do I expand function calls in a string?'' in this section
-of the FAQ.
+For other variations on the theme of text templates see the sprintf()
+function and numerous modules on CPAN.
=head2 What's wrong with always quoting "$vars"?
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.