5

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

'hello  world
'

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

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

4

2 回答 2

8

听起来像是其他人已经解决的问题。我从未使用过该模块,但它看起来很有用:

use String::Escape qw(unbackslash);
my $s = unbackslash('hello\tworld\n');
于 2010-04-17T21:51:21.793 回答
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;
于 2010-04-17T21:29:10.107 回答