5

perlで、のような文字列があり'hello\tworld\n'、必要なのは次のとおりです。

'hello  world
'

つまり、「hello」、次にリテラルのタブ文字、次に「world」、次にリテラルの改行です。または同等に"hello\tworld\n"(二重引用符に注意してください)。

つまり、エスケープシーケンスを含む文字列を取得し、すべてのエスケープシーケンスを補間した同等の文字列を返す関数はありますか?変数などを補間したくはありません。のようなシーケンスをエスケープするだけです。\xここxで、は文字です。

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%安全になりたい場合は、特に必要なサブでハッシュを作成し、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 に答える