How can I interpolate literal \t and \n in Perl strings? [duplicate]
Say I have an environment variable myvar
:
myvar=\tapple\n
When the following command will print out 开发者_如何学JAVAthis variable
perl -e 'print "$ENV{myvar}"'
I will literally have \tapple\n
, however, I want those control chars to be evaluated and not escaped. How would I achieve it?
In the real world $ENV
residing in substitution, but I hope the answer will cover that.
Use eval:
perl -e 'print eval qq{"$ENV{myvar}"}'
UPD: You can also use substitution with the ee
switch, which is safer:
perl -e '(my $s = $ENV{myvar}) =~ s/(\\n|\\t)/"qq{$1}"/gee; print $s'
You should probably be using String::Escape
.
use String::Escape qw(unbackslash);
my $var = unbackslash($ENV{'myvar'});
unbackslash
unescapes any string escape sequences it finds, turning them into the characters they represent. If you want to explicitly only translate \n
and \t
, you'll probably have to do it yourself with a s
ubstitution as in this answer.
There's nothing particularly special about a sequence of characters that includes a \
. If you want to substitute one sequence of characters for another, it's very simple to do in Perl:
my %sequences = (
'\\t' => "\t",
'\\n' => "\n",
'foo' => 'bar',
);
my $string = '\\tstring fool string\\tfoo\\n';
print "Before: [$string]\n";
$string =~ s/\Q$_/$sequences{$_}/g for ( keys %sequences );
print "After: [$string]\n";
The only trick with \ is to keep track of the times when Perl thinks it's an escape character.
Before: [\tstring fool string\tfoo\n]
After: [ string barl string bar
]
However, as darch notes, you might just be able to use String::Escape.
Note that you have to be extremely careful when you're taking values from environment variables. I'd be reluctant to use String::Escape
since it might process quite a bit more than you are willing to translate. The safe way is to only expand the particular values you explicitly want to allow. See my "Secure Programming Techniques" chapter in Mastering Perl where I talk about this, along with the taint checking you might want to use in this case.
精彩评论