Как я могу вручную интерполировать экранирование строк в строке Perl? - PullRequest
5 голосов
/ 18 апреля 2010

Предположим, в Perl у меня есть строка типа 'hello\tworld\n', и я хочу:

'hello  world
'

То есть «привет», затем буквенный символ табуляции, затем «мир», затем буквальный перевод строки. Или, что эквивалентно, "hello\tworld\n" (обратите внимание на двойные кавычки).

Другими словами, есть ли функция для взятия строки с escape-последовательностями и возврата эквивалентной строки со всеми интерполированными escape-последовательностями? Я не хочу интерполировать переменные или что-то еще, просто экранировать последовательности, такие как \x, где x это буква.

Ответы [ 2 ]

8 голосов
/ 18 апреля 2010

Звучит как проблема, которую кто-то другой уже решил бы . Я никогда не использовал модуль, но он выглядит полезным:

use String::Escape qw(unbackslash);
my $s = unbackslash('hello\tworld\n');
2 голосов
/ 18 апреля 2010

Вы можете сделать это с помощью '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% безопасным, я бы сделал хеш с теми подпрограммами, которые я специально хотел, и использовал бы замену регулярного выражения вместо eval:

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

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