String Perl字符串eq和or加在一起是真的

String Perl字符串eq和or加在一起是真的,string,perl,String,Perl,我正在使用xml::Parser解析xml;我的xml中有标记“my_id”和“total”。 当我尝试将两者与“或”组合时,它总是将if评估为true: if($elt eq "my_id" or "total") { return 1; $context = $elt; } 如果我打破它: if($name eq "my_id") { print($name." ".$xml_tag_val."\n"

我正在使用
xml::Parser
解析xml;我的xml中有标记“my_id”和“total”。
当我尝试将两者与“或”组合时,它总是将if评估为true:

if($elt eq "my_id" or "total")
{
               return 1;
               $context = $elt;
}
如果我打破它:

 if($name eq "my_id")
    {
          print($name." ".$xml_tag_val."\n");
          return 1;
    }
    elsif($name eq "total")
    {
           print($name." ".$xml_tag_val."\n");
          return 1;

    }
它工作得很好。
第一个if有什么问题?

您必须这样写您的条件:

if($elt eq "my_id" or $elt eq "total")

eq
不适用于“or”的左侧。
eq
的优先级更高,因此它首先测试该值

第一个表达式实际上是:

if ( $elt eq "my id"
          or "total" );
因为“total”是一个字符串,所以它是真的。你根本没有测试它的等价性

您可以重写为:

if ( $elt eq "my id"
  or $elt eq "total" ) {
  #.... 
}
$elt eq“我的id”或“总计”

正如其他人所指出的,这并不是在做你想要做的事情。加上括号,这相当于
($elt eq“my_id”)或“total”
。表达式始终为true,因为即使
$elt
的字符串不等于
“my_id”
,表达式的第二部分
“total”
,也是真实的表达式


perl的座右铭是“有多种方法可以做到这一点”;有很多方法可以测试
$elt
字符串是否等于
'my\u id'
'total'

if (($elt eq 'my_id') || ($elt eq 'total')) ...
if ($elt eq 'my_id' || $elt eq 'total') ...
我更喜欢上面的第一个。我的个人操作员偏好规则:除了
$a+$b*$c
等表达式外,请使用括号。
$a+$b*$c
不需要括号,因为大家都知道乘法和除法分布在加法和减法上。对于其他内容,请使用括号。但那只是我的偏好。做这件事的方法不止一种

if ($elt =~ /^(?:my_id|total)$/) ...
这是一种完全不同的方式。括号在这里很重要

另一种方法是,在以下情况下使用帖子:

return print("$name $xml_tag_val\n") if $elt =~ /^(?:my_id|total)$/;

你不需要那个“
$name.”“$xml\u tag\u val.”\n“
之类的东西。了解
“$non_interpolated_string”
“$interpolated_string”
之间的区别。单引号和双引号在perl中是完全不同的。

这里的主要问题是
不能以这种方式工作。这是关于
工作原理的常见误解。您可以在
eq
中使用表达式,但您使用的表达式使用
,其值低于
eq
,因此不属于字符串比较的一部分。此外,or表达式仅返回其参数之一,以对为准。对于字符串,除了
0
或空字符串之外的所有内容都是真的。这就是语句总是返回true的原因:
“total”
是Perl中的true表达式

你所写的内容可以用括号说明:

if( ( $elt eq "my_id") or "total")
#   ^----       -----^
您可以清楚地看到
或“total”
将使表达式始终为真。还要注意,这样做是错误的:

if( $elt eq ( "my_id" or "total") )
因为
:ed表达式总是返回
“my_id”
,甚至从不检查
“total”

您需要做的是对每个参数进行一次检查:

if( ($elt eq "my_id") or ($elt eq "total") )
或者,如果您有一个参数列表,并且
$elt
包含非假值(即
0
或空字符串,或
undef
),则可以使用
grep

if (grep { $elt eq $_ } @parameters)
或者更正确地使用
List::MoreUtils
中的
any
函数:

use List::MoreUtils qw(any);
if ( any { $elt eq $_ } @parameters )

/^(?:my_id | total)$/
可能会更好,除非您想捕获字符串。@TLP:Fixed。15号炭垫。总有不止一种方法。蒂姆·托迪·碳酸氢盐?就个人而言,我更喜欢Tim Toady而不是python的咒语,它说只有一种方法可以做到这一点。这就是说,现在我使用python比使用perl多得多。