【问题标题】:Equal strings are not equal in PerlPerl 中相等的字符串不相等
【发布时间】:2013-06-25 12:38:03
【问题描述】:

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

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

【问题讨论】:

  • 您没有提及defined($o_noreg) 是否为真。

标签: regex perl equality nagios


【解决方案1】:

当一个字符串被插入为一个正则表达式时,它不是字面匹配的,而是被解释为一个正则表达式。这对于构建复杂的正则表达式很有用,例如

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 不包含任何元字符。

【讨论】:

  • @TLP 可能会吹毛求疵,即。 /\Q$List/ vs /\Q$List\E/ 但很难说
  • @mpapec 结束转义序列是可选的。
猜你喜欢
  • 2011-08-27
  • 2015-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-10
  • 1970-01-01
相关资源
最近更新 更多