我要打印行:
my email is "abc@gmail.com"
使用perl脚本。
以下是我要执行的操作的摘要:
print "my email is \"abc@gmail.com\";
但是,当我运行程序时,无法识别@符号。如何调整代码段,以便显示@?
答案 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'";
最后,有时有用的另一种方法是使用printf
或sprintf
将变量插入“模板”字符串。这对于格式化带小数位的数字,添加前导零,用空格填充字符串等非常方便:
printf(qq{my email is "%s"\n}, $email);
由于换行,这又变得更加复杂了。如果不需要,则在格式字符串周围使用单引号会更容易:
printf('my email is "%s"', $email);