首页 > 解决方案 > 在perl中用引号打印@

问题描述

我想打印该行:

my email is "abc@gmail.com" 

使用 perl 脚本。

下面是我正在尝试做的一个片段:

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

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

标签: perlquotessymbols

解决方案


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};

然而,使用双引号的主要原因是允许对字符串中的变量进行“插值”(即:变量名将替换为变量的内容)。但是您的字符串不包含任何变量。所以一个更好的解决办法可能是只使用单引号,它不做变量插值,所以符号像@and$不是特殊的,不需要转义:

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);

推荐阅读