2015-10-13 42 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多得多。 –

相關問題