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

后端 未结 2 635
谎友^
谎友^ 2020-11-29 13:31

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

\'hello  world
\'

That is, \"hello\", then a li

相关标签:
2条回答
  • 2020-11-29 14:00

    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;
    
    0 讨论(0)
  • 2020-11-29 14:10

    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');
    
    0 讨论(0)
提交回复
热议问题