在perl中用引号打印@

Posted

技术标签:

【中文标题】在perl中用引号打印@【英文标题】:print @ in quotes in perl 【发布时间】:2019-01-02 21:09:34 【问题描述】:

我要打印该行:

my email is "abc@gmail.com" 

使用 perl 脚本。

下面是我正在尝试做的一个 sn-p:

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

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

【问题讨论】:

\@ 转义它或使用单引号。 perl 尝试插入列表变量时需要转义。请注意,您的第二行代码缺少终止双引号。 print "我的邮箱是\"abc\@gmail.com\""; @collapsar 是数组变量,不是列表变量。 Always use strictuse warnings 'all' 在您编写的每个 Perl 程序的顶部。 【参考方案1】:

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 qqmy 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 qqmy email is "$email";

或:

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

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

printf(qqmy email is "%s"\n, $email);

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

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

【讨论】:

酷。但是为什么use 5.012; 我本可以说use feature 'say'; 启用“新”say 功能,但use <version>; 检查 Perl 解释器是否至少是指定版本并启用该版本中的所有功能(包括say)。在这种情况下,任何高于 5.010 的版本都可以用于此目的。 5.12 已经足够老了,几乎无处不在。 是的,明白了,但是您的代码实际上并不需要任何新功能(或者是吗?),它使示例更简单。应该更清楚。 我期待你能到达say qmy email is abc@gmail.com;

以上是关于在perl中用引号打印@的主要内容,如果未能解决你的问题,请参考以下文章

perl 打印数组时加双引号区分不同元素

Perl 的 system() 如何打印它正在运行的命令?

Shell学习——终端打印

在perl中用MB替换M

为啥版本不能打印?

如何在双引号中打印字符串? (不打印双引号)