Perl中使用双冒号的奇数字符串解析

rqqzpn5f  于 2023-01-21  发布在  Perl
关注(0)|答案(3)|浏览(164)

我在Perl字符串解析中发现了一些奇怪的东西。下面是一个例子:

$word = "hello";
$test1 = "colon:values::$word:test";
$test2 = "colon:values::$word::test";

// test1 prints: "colon:values::hello:test"
// test2 prints: "colon:values::"

因此,如果Perl在字符串中的变量后看到双冒号,它(我假设)会认为您试图使用包名,我猜它试图加载“Hello::test”,但没有找到任何东西-因此提前终止字符串。
这正常吗?我发现这很违反直觉。我可以通过如下方式避开第一个冒号:

$works = "colon:values::$word\::test";

这是一个bug还是我完全忽略了一些明显的东西?

cedebl8k

cedebl8k1#

虽然这样做是可行的,但更普遍的处理方法是用大括号消除变量名称的歧义:

perl -E "my $word = 'red'; say qq|colon::values::${word}::test|"
colon::values::red::test

这在perldata中有记录:
在一些shell中,你可以用大括号将变量名括起来,以区分它与后面的字母数字(和下划线)。在将变量插入到字符串中时,你也必须这样做,以将变量名与后面的双冒号或撇号分隔开,因为否则它们将被视为包分隔符:

$who = "Larry";
print PASSWD "${who}::0:0:Superuser:/:/bin/perl\n";
print "We use ${who}speak when ${who}'s here.\n";

如果没有大括号,Perl将查找$whospeak$who::0$who's变量,最后两个变量将是(可能)不存在的包who中的$0$s变量。

pexxcrt2

pexxcrt22#

发生这种情况的原因是因为它试图将$word::test作为变量名来查找,正如您所正确推断的,包分隔符::是变量名的一部分,但它不会跟随$word的值,因为它在这里没有被用作符号引用(这需要更多语法)。
Oesor的解决方案可以解决你的问题--解决这类问题的一般方法是使用${identifier}语法。基本上,当你在字符串中插入一个变量,并且你需要在它后面跟一个有效的标识符字符或相关符号(例如::)时,可以使用它。

kiayqfof

kiayqfof3#

Perl使用命名空间作为变量名,当Perl看到::或一个'时,它会假设前面的是一个包(即命名空间)名。

use strict;
use warnings;    # You're using these? Aren't you?

my $foo = "bar"
print "The magic word is $foo_for_you\n";

由于下划线是变量名的有效字符,Perl假设您需要变量$foo_for_you,而不是$foo,并将_for_you附加到值上。那么,您认为这是一个 bug 还是一个 feature

print "The magic word is $foobar\n";   # Whoops! my variable is $foo.

解决这个问题的方法是绝对明确地说明$foo是您的变量:

print "The magic word is " . $foo . "_for_you\n";
printf "The magic word is %s_for_you\n", $foo;
print "The magic word is ${foo}_for_you\n";

同样的问题,如果你有$foo::for::you(或$foo'for'you)在这种情况下,Perl正在寻找一个名为$you的变量在命名空间foo::for中。

print "The magic word is " . $foo . "::for::you\n";
printf "The magic word is %d::for::you\n", $foo;
print "The magic word is ${foo}::for::you\n";

命名空间用于防止Perl模块中的变量修改程序中的变量。想象一下,调用Perl包中的函数,突然发现程序中使用的变量被更改了。
看看File::Find,您可以看到附加了包名称空间的变量($File::Find::name$File::Find::dir是两个示例)。

相关问题