【问题标题】:How can I manually interpolate string escapes in a Perl string?如何在 Perl 字符串中手动插入字符串转义?
【发布时间】:2011-02-09 05:57:15
【问题描述】:

在 perl 中假设我有一个类似'hello\tworld\n' 的字符串,而我想要的是:

'hello  world
'

即“hello”,然后是文字制表符,然后是“world”,然后是文字换行符。或者等效地,"hello\tworld\n"(注意双引号)。

换句话说,是否有一个函数可以获取一个带有转义序列的字符串并返回一个插入了所有转义序列的等效字符串?我不想插入变量或其他任何东西,只是像\x 这样的转义序列,其中x 是一个字母。

【问题讨论】:

    标签: perl escaping string-interpolation


    【解决方案1】:

    听起来像是其他人会遇到的问题solved already。我从未使用过该模块,但它看起来很有用:

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

    【讨论】:

    • 非常感谢。我找到了 String::Interpolate,但它的作用完全不同。
    • 另外,对于在 Ubuntu 9.10 中使用它的人,String::Escape 的版本没有unbackslash。相反,它有unprintable
    【解决方案2】:

    你可以用'eval'来做到这一点:

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

    请注意,如果您不能 100% 控制输入字符串,则该方法存在安全问题。

    编辑:如果您只想插入 \x 替换(而不是“任何 Perl 将插入带引号的字符串”的一般情况),您可以这样做:

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

    这与 quotemeta 的作用几乎相同 - 但不会对“\”字符进行转义。

    Edit2:这仍然不是 100% 安全的,因为如果最后一个字符是 '\' - 它会“泄漏”到字符串的末尾...

    就个人而言,如果我想 100% 安全,我会使用我特别想要的 subs 进行哈希,并使用正则表达式替换而不是 eval:

    my %sub_strings = (
        '\n' => "\n",
        '\t' => "\t",
        '\r' => "\r",
    );
    
    $string =~ s/(\\n|\\t|\\n)/$sub_strings{$1}/gs;
    

    【讨论】:

    • 我可以使用evalquotemeta 的组合来安全地执行此操作吗?基本上,(my $interpolated_string = eval(q(") . quotemeta($string) . q("))) =~ s/\\(.)/\1/g.
    • 如果没有它也会杀死插值。 ;)
    • 好吧,我只想插入\x,其中x 是任何字母。不是变量或其他东西。
    猜你喜欢
    • 2011-03-04
    • 1970-01-01
    • 2019-12-18
    • 1970-01-01
    • 2014-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-26
    相关资源
    最近更新 更多