プロが教えるわが家の防犯対策術!

Perlで、変数に既に格納されているエスケープされた特殊文字を、もとの文字に展開するには
どのようにしたらよいでしょうか。
つまり、\t という値で格納されているのをタブ文字にしたり、\\ という値であれば\の一文字に
するという事です。

ダブルクォートで定義すれば展開されると思いましたが、展開は変数の代入時に行われるだけで、
既に変数中にエスケープされて入っているものはダブルクォートを使い変数を囲んだりしても展開されません。

下記は簡単な例でやろうとしてる事を示したものです。
add変数に\tというタブを意味するエスケープされた特殊文字を含んでいるとして、その\tを
タブとして展開し、abc defのようにさせたいのですが、abc\tdefと入ってしまいます。

$ cat unescape.pl
#!/bin/perl

$add = '\tdef'; #シングルクォートで代入すると、もちろんエスケープされたまま代入される
#$add = "\tdef"; #ダブルクォートで代入すると代入時にタブへ展開される
#$add = $ARGV[0]; #本当はAGRVからエスケープ特殊文字を含んだ文字列を取りたい。ARGVから代入すると、シングルクォートの時のようにそのまま代入される
$tgt = 'abc';

print "add: " . $add , "\n";
print "before: " . $tgt . "\n";
$tgt .= "$add"; #既にエスケープされた形で代入されているものを、ダブルクォートで囲んで使っても展開されない
print "after: " . $tgt . "\n";


$ perl unescape.pl
add: \tdef
before: abc
after: abc\tdef

A 回答 (3件)

eval を使えば出来そうです。



例)
$hoge = 'hoge\thoge\n';
print eval "\"$hoge\"";


ARGVの値でやると引数次第で任意のコードが実行できてしまうので、間接的に第3者から実行される可能性のあるプログラムなどでは危険ですが・・・。

参考URL:http://itpro.nikkeibp.co.jp/article/Reference/20 …
    • good
    • 0

脆弱性を考えなくて良い状況なら、eval を使えば簡単です。



$a = 'a\tb\n';
print $a , "\n";

$b = eval("\"$a\"");
print $b , "\n";

$a の値が信頼できない場合は、

$b = $a;
$b =~ s/\\t/\t/g;
$b =~ s/\\n/\n/g;
・・・・・
print $b , "\n";

のように必要なだけ置換するくらいでしょうか。
    • good
    • 0

2文字限定でよければ、正規表現の置換を使って変換することができると思います。



my $foo = $ARGV[0];
$foo =~ s/\\./qq("$&")/eeg;
print "$foo\n";

$ perl unescape.pl 'abc\tdef\\ghi'
abc   def\ghi

シングルクォート内での \\ の扱いは、Bash と Perl では異なります。Bash では \\ のままですが、Perl では \\ を \ に変換します。
    • good
    • 0
この回答へのお礼

ありがとうございます。この方式で行くことにしました。

お礼日時:2014/09/02 05:57

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!