Perl中的等字符串不相等

Jak*_*sky 3 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");
   }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是我没有写它但我必须理解它.$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)           ==>
Run Code Online (Sandbox Code Playgroud)

如您所见,输出第二行中的字符串相等.那为什么不是$test真的呢?


编辑:我已经打印了一些更多的输出,并发现,当$descr_d eq $List它,它等于,但不是如果$descr_d =~ $List.你能解释一下这个$test变量究竟是什么吗?我不明白defined() ? :这里的意思是什么.


EDIT2:对于字符串"SQL Server Agent",脚本工作正常,只有附加(C4)时才会出现问题.很奇怪,不是吗?

amo*_*mon 10

当字符串作为正则表达式进行插值时,字面上不匹配,而是解释为正则表达式.这对于构建复杂的正则表达式非常有用,例如

my @animals = qw/ cat dog goldfish /;
my $animal_re = join "|", @animals;

say "The $thing is an animal" if $thing =~ /$animal_re/i;
Run Code Online (Sandbox Code Playgroud)

在字符串中$animal_re,它|被视为正则表达式元字符.

其他元字符例如(...)捕获组.这存在于你的$List.也就是说,你的正则表达式实际上是在寻找字符串SQL Server C4C4在成功时捕获它.

要取消激活元字符,您可以引用它们

/\Q$metachars\E/
Run Code Online (Sandbox Code Playgroud)

在你的情况下:

$test = defined($o_noreg)
      ? $descr_d eq $List
      : $descr_d =~ /\Q$List/i;
Run Code Online (Sandbox Code Playgroud)

另外,Perl的默认false值是空字符串.如果您将其强制转换为数字,则输出可能更具可读性,例如通过$test += 0.打印出引号括起来的字符串可能也会有所帮助:

print qq("$descr_d" = "$List"\t==> $test\n);
Run Code Online (Sandbox Code Playgroud)

回复:你的编辑

条件运算符是类似C语言中常见的.它由三部分组成:

COND ? EXPR_A : EXPR_B
Run Code Online (Sandbox Code Playgroud)

如果条件COND为真,EXPR_A则计算表达式; 否则EXPR_B就是.在您的代码中,已分配已计算的表达式的值$test.

defined内建测试是否标持有价值undef.如果是这种情况,则返回false值,1否则返回false值.这里用于某些配置:当$o_noreg设置为除了之外的任何值时undef,将使用默认字符串比较.如果是undef,则执行正则表达式.

回复:编辑2

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

  • 这是我今天无缘无故地看到的第四个Perl答案. (2认同)