Perl中的等字符串不相等

时间:2013-06-25 12:38:04

标签: regex perl equality nagios

请帮助我理解字符串相等的一个奇怪问题。 这是我正在谈论的代码:

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)时才会出现问题。很奇怪,不是吗?

1 个答案:

答案 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,则将执行正则表达式。

回复:编辑2

不奇怪:SQL Server (C4)包含()元字符,而SQL Server Agent不包含任何元字符。