在 Perl 中用引号括起来打印 @

print @ in quotes in perl

提问人:jms1980 提问时间:7/26/2018 更新时间:7/26/2018 访问量:2730

问:

我想打印以下行:

my email is "[email protected]" 

使用 Perl 脚本。

以下是我正在尝试做的事情的片段:

print "my email is \"[email protected]\";

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

Perl 引用符号

评论

6赞 Matt Jacob 7/26/2018
使用单引号或使用单引号转义它。\@
1赞 collapsar 7/26/2018
perl 尝试插值列表变量时需要转义,否则。请注意,第二行代码缺少终止双引号。
1赞 Ted Bear 7/26/2018
打印“我的电子邮件是 \”abc\@gmail.com\“”;
2赞 Matt Jacob 7/26/2018
@collapsar 它是一个数组变量,而不是列表变量。
3赞 Borodin 7/26/2018
始终在你编写的每个 Perl 程序的顶部。use strictuse warnings 'all'

答:

9赞 Grant McLean 7/26/2018 #1

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

首先,你没有提到你得到了什么输出。假设您在脚本顶部有一些合理的默认样板,例如......

#!/usr/bin/perl

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

然后这行代码......

print "my email is \"[email protected]\"\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正在将符号解释为数组名称的开头。因此,它采用后面的“单词”并将其用作标识符名称,并认为您正在尝试引用数组变量。由于脚本没有声明该数组与任何地方,因此将抛出致命异常。(注意:我稍微调整了您的代码以在末尾添加换行符)。@@gmailmy @gmailuse strict\n

您可以进行的最简单的更改是在符号前面放置一个反斜杠 () 以“转义”它 - 即:告诉 Perl 你只需要一个字符,这不是数组标识符的开头。\@\@@

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

这看起来确实有点凌乱。一个原因是你有一个双引号的字符串,里面有双引号,所以它们也用 转义。表示双引号字符串的另一种方法是使用运算符,然后选择自己的字符串分隔符。在这里,我使用大括号作为分隔符,因此不再需要对嵌入的双引号进行转义:\"qq

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

但是,使用双引号的主要原因是允许字符串中的变量被“插值”(即:变量名称将被替换为 va riable 的内容)。但是您的字符串不包含任何变量。因此,更好的解决方法可能是只使用单引号,它不进行变量插值,因此像 和 这样的符号不是特殊的,不需要转义:@$

print 'my email is "[email protected]"', "\n";

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

my $message = 'my email is "[email protected]"' . "\n";

但是,如果使用双引号的唯一原因是在打印的末尾添加换行符,那么您可以改用与打印完全相同的函数,但它在末尾添加了一个换行符:say

say 'my email is "[email protected]"';

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

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

my $email = '[email protected]';
say qq{my email is "$email"};

艺术

my $email = '[email protected]';
say "my email is '$email'";

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

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

由于换行符,这再次变得更加复杂。如果您不需要它,那么在格式字符串周围使用单引号会更容易:

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

评论

1赞 Robert 7/26/2018
凉。但为什么呢?use 5.012;
0赞 Grant McLean 7/26/2018
我本可以说启用“新”功能,但检查Perl解释器是否至少是指定的版本,并启用该版本中的所有功能(包括)。在这种情况下,任何高于 5.010 的版本都可以用于此目的。5.12 已经足够老了,几乎可以无处不在。use feature 'say';sayuse <version>;say
0赞 Robert 7/26/2018
是的,理解,但是您的代码实际上并不需要任何新功能(或者是吗?),并且它使示例更简单。应该把这一点说得更清楚。
0赞 Sobrique 7/26/2018
我期待你到达say q{my email is [email protected]};