如何将单引号字符串转换为双引号字符串,以便解释?

时间:2011-04-04 23:49:41

标签: perl string quote

例如我有,

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

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

"My String is \t"

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

4 个答案:

答案 0 :(得分:4)

String::Interpolate正是这样做的

$ perl -MString::Interpolate=interpolate -E 'say "My String is [". interpolate(shift) . "]"' '\t'
My String is [  ]

答案 1 :(得分: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;

答案 2 :(得分: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';

我可以这样做的一种方法是使用替换运算符和double / e标志。第一个/ e在替换方评估$ 1并将其变为$ foo。第二个/ e以$ foo开头并用它的值替换它。然后,$ foo变成'Fred',那最后剩下的就是字符串:

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

/ e也会默默地忽略违反strict的行为,用空字符串替换未定义的变量名。因为我正在使用/ 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;

答案 3 :(得分: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