我经历了使用正则表达式捕获来分配列表元素的奇怪行为 - 这让我很困惑,而且我在文档和其他地方的任何地方都找不到解释。我使用的代码是这样的:
$_ = "one 1 two 2 three 3";
my $n = 1;
my @tt = (
/one (\S+)/ ? (one => $1) : (),
/two (\S+)/ ? (two => $1) : (),
/three (\S+)/ ? (three => $1) : (),
);
print "Array: " . join(" ", @tt) . "\n";
出人意料地打印出来:
Array: one 3 two 3 three 3
虽然我希望它会打印出来:
Array: one 1 two 2 three 3
因此,当我在列表赋值中使用//
和?:
时,我总是从最后一个(!)匹配表达式获取捕获 - 无论是$1
还是$&
或其他任何涉及捕获的内容。
当我用?:
围绕每个do {}
时,一切都按预期工作。
我的问题是 - 我做错了什么?这是一个我不知道的错误或一些众所周知(或隐藏)的功能/行为吗?
谢谢!
PS:如果这很重要 - 我在Ubuntu 16.04.2上使用标准的perl 5.22.1,尽管Perl 5.8.8和5.24.1上的行为是相同的编辑:虽然这种行为的原因与此问题相同 - compilation order and post prefix opertors - 但上下文完全不同,问题是相似的并不是很明显,因为前面的问题是关于将参数传递给子,而在我的问题中没有涉及潜艇。
答案 0 :(得分:4)
compilation order and post prefix opertors的答案也回答了你的问题。以下是摘要。
一般来说,避免在表达式 [1] 中设置和读取变量的情况。
您的代码执行以下操作:
$1
。$1
。 (不是$1
的副本!)$1
。$1
。$1
。$1
。$1
,字符串,$1
,字符串,$1
)复制到@tt
。此时$1
为3
。您可以使用"$1"
代替$1
解决此问题,因为"$1"
会从$1
构建新字符串。
my $x = /(foo|bar)/ ? $1 : 'default';
不会给你任何问题。