В жемчуге предполагают, что у меня есть строка как 'hello\tworld\n'
, и то, что я хочу:
'hello world
'
Таким образом, "привет", затем литеральный символ табуляции, затем "мир", затем литеральная новая строка. Или эквивалентно, "hello\tworld\n"
(отметьте двойные кавычки).
Другими словами, существует ли функция для взятия строки с escape-последовательностями и возвратом эквивалентной строки со всеми интерполированными escape-последовательностями? Я не хочу интерполировать переменные или что-либо еще, просто escape-последовательности как \x
, где x
буква.
Похоже на проблему, которую кто-то другой уже решил . Я никогда не использовал этот модуль, но он выглядит полезным:
use String::Escape qw(unbackslash);
my $s = unbackslash('hello\tworld\n');
Вы можете сделать это с помощью 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 % safe Я бы сделал хеш с подпрограммами, которые мне были нужны, и использовал бы замену регулярным выражением вместо eval:
my %sub_strings = (
'\n' => "\n",
'\t' => "\t",
'\r' => "\r",
);
$string =~ s/(\\n|\\t|\\n)/$sub_strings{$1}/gs;