请帮助我理解字符串相等的一个奇怪问题。 这是我正在谈论的代码:
my $test=undef;
foreach my $List (@o_descrL) {
if (!($test)) {
$test = defined($o_noreg)
? $descr_d eq $List
: $descr_d =~ /$List/i;
printf("$descr_d = $List\t\t==> $test\n");
}
}
不幸的是我没有写它但我必须理解它。 $List
始终是“SQL Server(C4)”,$descr_d
正在根据数组中的实际项目进行更改。打印输出的一部分在这里:
Power = SQL Server (C4) ==>
SQL Server (C4) = SQL Server (C4) ==>
SNMP Service = SQL Server (C4) ==>
Network Connections = SQL Server (C4) ==>
如您所见,输出第二行中的字符串相等。那么为什么$test
不是真的呢?
编辑:我已经打印了更多输出,发现当$descr_d eq $List
时,它等于,但不是$descr_d =~ $List
。你能解释一下$test
变量的实际内容吗?我不明白defined() ? :
在这里的意思。
EDIT2:对于字符串“SQL Server Agent”,脚本工作正常,只有附加(C4)时才会出现问题。很奇怪,不是吗?
答案 0 :(得分:10)
当字符串被插值为正则表达式时,字面上不匹配,而是解释为正则表达式。这对于构建复杂的正则表达式非常有用,例如
my @animals = qw/ cat dog goldfish /;
my $animal_re = join "|", @animals;
say "The $thing is an animal" if $thing =~ /$animal_re/i;
在字符串$animal_re
中,|
被视为正则表达式元字符。
其他元字符例如是(...)
,这是捕获组。这存在于您的$List
中。也就是说,你的正则表达式实际上是在寻找字符串SQL Server C4
并在成功时捕获C4
。
要停用元字符,您可以引用它们,如
/\Q$metachars\E/
在你的情况下:
$test = defined($o_noreg)
? $descr_d eq $List
: $descr_d =~ /\Q$List/i;
另外,Perl的默认false值是空字符串。如果您将其强制转换为数字,则输出可能更具可读性,例如通过$test += 0
。打印出引号括起来的字符串也可能有帮助:
print qq("$descr_d" = "$List"\t==> $test\n);
条件运算符在类C语言中很常见。它由三部分组成:
COND ? EXPR_A : EXPR_B
如果条件COND
为真,则计算表达式EXPR_A
;否则,EXPR_B
是。在您的代码中,已评估的表达式的值被分配给$test
。
defined
内置函数测试标量所持有的值是undef
。如果是这种情况,则返回false值,否则返回1
。这在此处用于某些配置:当$o_noreg
设置为除undef
之外的任何值时,将使用默认字符串比较。如果是undef
,则将执行正则表达式。
不奇怪:SQL Server (C4)
包含(
和)
元字符,而SQL Server Agent
不包含任何元字符。