How can I manually interpolate string escapes in a Perl string?

半城伤御伤魂 提交于 2019-11-26 10:02:32

问题


In perl suppose I have a string like \'hello\\tworld\\n\', and what I want is:

\'hello  world
\'

That is, \"hello\", then a literal tab character, then \"world\", then a literal newline. Or equivalently, \"hello\\tworld\\n\" (note the double quotes).

In other words, is there a function for taking a string with escape sequences and returning an equivalent string with all the escape sequences interpolated? I don\'t want to interpolate variables or anything else, just escape sequences like \\x, where x is a letter.


回答1:


Sounds like a problem that someone else would have solved already. I've never used the module, but it looks useful:

use String::Escape qw(unbackslash);
my $s = unbackslash('hello\tworld\n');



回答2:


You can do it with 'eval':

my $string = 'hello\tworld\n';
my $decoded_string = eval "\"$string\"";

Note that there are security issues tied to that approach if you don't have 100% control of the input string.

Edit: If you want to ONLY interpolate \x substitutions (and not the general case of 'anything Perl would interpolate in a quoted string') you could do this:

my $string = 'hello\tworld\n';
$string =~ s#([^\\A-Za-z_0-9])#\\$1#gs;
my $decoded_string = eval "\"$string\"";

That does almost the same thing as quotemeta - but exempts '\' characters from being escaped.

Edit2: This still isn't 100% safe because if the last character is a '\' - it will 'leak' past the end of the string though...

Personally, if I wanted to be 100% safe I would make a hash with the subs I specifically wanted and use a regex substitution instead of an eval:

my %sub_strings = (
    '\n' => "\n",
    '\t' => "\t",
    '\r' => "\r",
);

$string =~ s/(\\n|\\t|\\n)/$sub_strings{$1}/gs;


来源:https://stackoverflow.com/questions/2660123/how-can-i-manually-interpolate-string-escapes-in-a-perl-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!