2015-10-13 38 views
0

我使用XML::Parser解析xml;我在我的XML中有“my_id”和“total”标签。
当我尝试都与“或”结合起来,它始终评估,如果是真的:Perl字符串eq和或在一起alwas是真的

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; 

    } 

它工作得很好。 第一个错在哪里?

回答

3

你必须写你的情况是这样的:

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

eq不适的“或”左手侧。 eq的优先级较高,因此首先进行测试。

,首先表现居然是:

if ($elt eq "my id" 
      or "total"); 

因为“总”是一个字符串,它是真实的,因此。你根本没有测试它是否等同。

你可以为改写:

if ($elt eq "my id" 
    or $elt eq "total") { 
    #.... 
} 
0

$elt eq "my_id" or "total"

正如其他人指出,这是不是你做什么打算。用括号表示,这相当于($elt eq "my_id") or "total"。该表达式总是如此,因为即使$elt不是字符串等于"my_id",表达式的第二部分"total"也是真值表达式。


perl的座右铭是“有多种方法可以做到这一点”。这当然适用于此;有很多方法可以测试$elt是否为字符串等于'my_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_tag_val."\n"东西。了解'$non_interpolated_string'"$interpolated_string"之间的区别。单引号和双引号是perl中相当不同的野兽。

+0

'/ ^(?: my_id | total)$ /'可能会更好,除非你想捕获一个字符串。 – TLP

+0

@TLP:已修复。 15_char_pad。 –

4

这里的主要问题是or不能这样工作。这是关于or如何工作的常见误解。您可以使用eq中的表达式,但是您使用的表达式使用or,它具有比eq更低的precedence,因此不是字符串比较的一部分。另外,or表达式只返回其中一个参数,无论哪个都是真实的。并且对于字符串,除0或空字符串以外的所有内容都为真。这就是你的陈述总是返回true的原因:"total"在Perl中是一个真正的表达式。

你所写的内容可以用括号予以澄清:

if(($elt eq "my_id") or "total") 
# ^----  -----^ 

在这里你可以清楚地看到,or "total"将使表达总是如此。还需要注意的是这将是错误做到这一点:

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

因为or: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) 
+0

总有不止一种方法可以做到这一点。 –

+0

所有概括都是错误的。你不知道吗? – TLP

+0

Tim Toady碳酸氢盐?就我个人而言,我更喜欢Tim Toady关于python的口头禅,说只有一种方法可以做到这一点。也就是说,现在我使用python比使用perl多得多。 –

相关问题