匹配运算符左侧的数组

时间:2019-04-09 23:43:32

标签: regex perl

当左侧是数组时,发现脚本的怪异行为:

#!/usr/bin/perl

sub say {
    print @_, "\n";
}


my @arr = ('I', 'am', 'Qiang');
if (@arr =~ /Qiang/) {
    say("1: Match!!!");
} else {
    say("1: No match found");
}

@arr = ('Qiang');
if (@arr =~ /Qiang/) {
    say("2: Match!!!");
} else {
    say("2: No match found");
}

if (('Qiang') =~ /Qiang/) {
    say("3: Match!!!");
} else {
    say("3: No match found");
}
qxu@xqiang-mac-0:~/test$ ./regex_array_match.pl 
1: No match found
2: No match found
3: Match!!!

第二种情况和第三种情况下的代码看起来与我相同,但结果不同。

当匹配运算符的左侧显示一个数组时,Perl应该做什么?

1 个答案:

答案 0 :(得分:4)

=~运算符在标量上下文(它需要一个字符串)中评估其左操作数。

标量上下文中的数组会产生其包含的元素数量,在您的情况下分别为31

因此条件变为"3" =~ /Qiang/"1" =~ /Qiang/,它们都是错误的。

如果您use strict; use warnings;(始终应该这样做),则会看到以下警告:

Applying pattern match (m//) to @arr will act on scalar(@arr)

...其中perldoc perldiag explains as

  

(W misc)模式匹配(//),替换(s///)和音译(tr///)运算符适用于标量值。如果将其中之一应用于数组或哈希,它将把数组或哈希转换为标量值(数组的长度或哈希的填充信息),然后对该标量值进行处理。这可能不是您的本意。有关替代方法,请参见"grep" in perlfunc"map" in perlfunc


要检查数组的任何元素是否与正则表达式模式匹配,可以使用grep,如下所示:

my @arr = ('I', 'am', 'Qiang');
if ( grep { /Qiang/ } @arr ) {
    say("At least one match!!!");
} else {
    say("No match found");
}

grep在标量上下文中求值时实际上会返回匹配元素的数量,因此效率不如预期(它将始终检查每个数组元素)。要在找到第一个匹配项后停止检查,请使用any from List::Util