在perl中用引号显示@

时间:2018-07-25 23:56:29

标签: perl quotes symbols

我要打印行:

my email is "abc@gmail.com" 

使用perl脚本。

以下是我要执行的操作的摘要:

print "my email is \"abc@gmail.com\";

但是,当我运行程序时,无法识别@符号。如何调整代码段,以便显示@?

1 个答案:

答案 0 :(得分:7)

Perl社区的座右铭之一是“做到这一点的方法不止一种”。在这种情况下,有很多方法可以实现您要完成的任务,每种方法在不同情况下都具有优势。我在下面说明了一些答案。

首先,您没有提到获得的输出。假设您在脚本顶部有一些明智的默认样板...

#!/usr/bin/perl

use 5.012;
use strict;
use warnings;
use autodie;

然后这行代码...

print "my email is \"abc@gmail.com\"\n";

应该给您类似的错误消息:

Possible unintended interpolation of @gmail in string at ./ptst.pl line 10.
Global symbol "@gmail" requires explicit package name at ./ptst.pl line 10.
Execution of ./ptst.pl aborted due to compilation errors.

这是在告诉您Perl会将@符号解释为数组名称的开头。因此,它使用后面的“单词”并将其用作标识符名称,并认为您正在尝试引用数组变量@gmail。由于脚本未在任何地方声明带有my @gmail的数组,因此use strict将引发致命异常。 (注意:我对您的代码进行了一些调整,以包括\n并在末尾添加换行符。)

您可以做的最简单的更改是,在\符号前加一个反斜杠(@)以“转义”它-即:\@告诉Perl想要一个@字符,这不是数组标识符的开始。

print "my email is \"abc\@gmail.com\"\n";

这看起来有点混乱。原因之一是您有一个双引号字符串,其中带有双引号,因此它们也被\"转义。表示双引号字符串的另一种方法是使用qq运算符,然后选择自己的字符串定界符。在这里,我使用花括号作为定界符,因此不再需要转义嵌入的双引号:

print qq{my email is "abc\@gmail.com"\n};

但是使用双引号的主要原因是允许对字符串中的变量进行“插值”(即:变量名将替换为变量的内容)。但是您的字符串不包含任何变量。因此,更好的解决方案可能是仅使用单引号,而不进行变量插值,因此@$之类的符号并不特殊,不需要转义:

print 'my email is "abc@gmail.com"', "\n";

不幸的是,双引号所做的另一件事是允许您使用特殊的序列,例如\n用于换行符或\t用于制表符。在我的示例中,我需要换行符,因此我利用了print函数接受参数列表并为其传递两个字符串的事实:第一个使用单引号以避免转义,第二个使用双引号允许转义序列。在必须使用单个字符串而不是逗号分隔符的另一种情况下,可以使用.运算符将两个字符串连接成一个字符串:

my $message = 'my email is "abc@gmail.com"' . "\n";

但是,如果使用双引号的唯一原因是在打印的末尾添加换行符,则可以改用say函数,该函数与print完全相同,但会在打印的末尾添加换行符结束:

say 'my email is "abc@gmail.com"';

如果您尝试这样做并收到类似(Do you need to predeclare say?)的错误,那是因为您缺少我一开始提到的样板行。

您的原始脚本没有使用变量,但是添加变量将是解决问题的另一种方式:

my $email = 'abc@gmail.com';
say qq{my email is "$email"};

或:

my $email = 'abc@gmail.com';
say "my email is '$email'";

最后,有时有用的另一种方法是使用printfsprintf将变量插入“模板”字符串。这对于格式化带小数位的数字,添加前导零,用空格填充字符串等非常方便:

printf(qq{my email is "%s"\n}, $email);

由于换行,这又变得更加复杂了。如果不需要,则在格式字符串周围使用单引号会更容易:

printf('my email is "%s"', $email);