0

例如我有,

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

我希望输出解释制表符并返回如下内容:

"My String is \t"

我实际上是从数据库中获取字符串的值,并将其作为单引号字符串返回。

4

4 回答 4

4

'\t'"\t"字符串文字,是产生字符串(分别为“\”、“t”和制表符)的 Perl 代码片段。数据库不返回 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;
于 2011-04-05T03:58:52.567 回答
4

您可以按照perlfaq4How can I expand variables in text strings? 的回答中的技术进行操作?


如果可以避免,请不要这样做,或者如果您可以使用模板系统,例如 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';

我可以做到这一点的一种方法涉及替换运算符和双 /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;
于 2011-04-05T05:30:42.727 回答
4

String::Interpolate正是这样做的

$ perl -MString::Interpolate=interpolate -E 'say "My String is [". interpolate(shift) . "]"' '\t'
My String is [  ]
于 2011-04-05T00:15:24.897 回答
0

好吧,我只是尝试了以下解决方法,它起作用了。请看一看

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
于 2013-07-18T10:20:58.250 回答