Как преобразовать строку с одинарными кавычками в строку с двойными кавычками, чтобы ее интерпретировали? - PullRequest
0 голосов
/ 05 апреля 2011

Например, у меня есть,

my $str = '\t';
print "My String is ".$str;

Я хочу, чтобы вывод интерпретировал символ табуляции и возвращал что-то вроде:

"My String is \t"

Я на самом деле получаю значение строки из базы данных и возвращает его в виде строки в одинарных кавычках.

Ответы [ 4 ]

4 голосов
/ 05 апреля 2011

'\t' и "\t" - это строковые литералы , фрагменты кода Perl, который генерирует строки ("\", "t" и символ табуляции соответственно). База данных не возвращает код Perl, поэтому описывать проблему с помощью литералов в одинарных и двойных кавычках не имеет смысла. У вас есть строка, точка.

Строка состоит из символов "\" и "t". Вы хотите преобразовать эту последовательность символов в символ табуляции. Это простая замена.

s/\\t/\t/g

Полагаю, вы не хотите иметь дело только с \t. Вы можете создать таблицу последовательностей.

my %escapes = (
    "t" => "\t",
    "n" => "\n",
    "\" => "\\",
);

my $escapes_pat = join('', map quotemeta, keys(%escapes));
$escapes_pat = qr/[$escapes_pat]/;

s/\\($escapes_pat)/$escapes{$1}/g;
4 голосов
/ 05 апреля 2011

Вы можете следовать технике в ответе perlfaq4 на Как я могу расширить переменные в текстовых строках? :


Если вы можете избежать этого, не, или если вы можете использовать систему шаблонов, такую ​​как Text :: Template или Template Toolkit, сделайте это вместо этого.Возможно, вы даже сможете выполнить работу с помощью sprintf или printf:

my $string = sprintf 'Say hello to %s and %s', $foo, $bar;

Однако для одноразового простого случая, когда я не хочу использовать полную систему шаблонов, яиспользуйте строку с двумя скалярными переменными Perl.В этом примере я хочу расширить $ foo и $ bar до значений их переменных:

my $foo = 'Fred';
my $bar = 'Barney';
$string = 'Say hello to $foo and $bar';

Один из способов сделать это - оператор подстановки и флаг double / e.Первый / e оценивает $ 1 на стороне замены и превращает его в $ foo.Секунда / e начинается с $ foo и заменяет его значением.Затем $ foo превращается в 'Fred', и это, наконец, то, что осталось в строке:

$string =~ s/(\$\w+)/$1/eeg; # 'Say hello to Fred and Barney'

/ e также будет молча игнорировать нарушения строгих правил, заменяя неопределенные имена переменных пустой строкой.Поскольку я использую флаг / e (даже дважды!), У меня все те же проблемы с безопасностью, что и у меня с eval в его строковой форме.Если в $ foo есть что-то странное, возможно, что-то вроде @ {[system "rm -rf /"]}, то у меня могут возникнуть проблемы.

Чтобы обойти проблему безопасности, я мог бы также потянутьзначения из хеша вместо оценки имен переменных.Используя один / e, я могу проверить хеш, чтобы убедиться, что значение существует, и если его нет, я могу заменить отсутствующее значение маркером, в этом случае ???сигнализировать, что я что-то пропустил:

my $string = 'This has $foo and $bar';

my %Replacements = (
    foo  => 'Fred',
    );

# $string =~ s/\$(\w+)/$Replacements{$1}/g;
$string =~ s/\$(\w+)/
    exists $Replacements{$1} ? $Replacements{$1} : '???'
    /eg;

print $string;
4 голосов
/ 05 апреля 2011

String :: Interpolate делает именно это

$ perl -MString::Interpolate=interpolate -E 'say "My String is [". interpolate(shift) . "]"' '\t'
My String is [  ]
0 голосов
/ 18 июля 2013

Ну, я только что попробовал ниже обходной путь, он работалПожалуйста, посмотрите

my $str1 = "1234\n\t5678";
print $str1; 
#it prints 
#1234
#     5678

$str1 =~ s/\t/\\t/g;
$str1 =~ s/\n/\\n/g;

print $str1; 
#it prints exactly the same
#1234\n\t5678
...