Re: [問題] perl grep()與$_

看板Perl作者 (啊)時間15年前 (2010/07/24 01:56), 編輯推噓4(400)
留言4則, 4人參與, 最新討論串2/2 (看更多)
※ 引述《nuzleaf (送高中參考書)》之銘言: : 各位大大您好 我是一個perl新手 有很多問題想請教 : 不過都是為了de一個bug來的 謝謝! : a. grep(A,B) A的部分是不是一定要放regular expression? : 假設我 $str= "perl_newbie"; @result = grep($str,@array); : 這樣好像會回傳所有array的值 而grep(/$str/,@array)才能找到 : array裡相對應的值 不知道我有沒有搞錯 那前者為什麼沒有compile error? grep 的第一個參數也可以是 block (code ref), 不過這與您的問題沒有直接關係。 事實上這是個很有意思的問題。在此引用 'perldoc -f grep' 前兩段: grep BLOCK LIST grep EXPR,LIST This is similar in spirit to, but not the same as, grep(1) and its relatives. In particular, it is not limited to using regular expressions. Evaluates the BLOCK or EXPR for each element of LIST (locally setting $_ to each element) and returns the list value consisting of those elements for which the expression evaluated to true. In scalar context, returns the number of times the expression was true. 基本上寫 grep($str, @array) 與 grep(/re/, @array) 對應到的都是第二 種語法。而這種語法的解讀方式是: 將每個 @array 裡的值一一設成 $_ 後,去取 EXPR 的值 如果 EXPR 是 /re/ 的話,發生的事就像是 $_ = $array[0]; if (/re/) { push @result, $_ } $_ = $array[1]; if (/re/) { push @result, $_ } # ... 如此這般一直重複下去 如果 EXPR 是 $str 的話,則是 $_ = $array[0]; if ($str) { push @result, $_ } $_ = $array[1]; if ($str) { push @result, $_ } # ... 如此這般 也就是說,if ($str) 的部份永遠會成立,@result 的內容自然也就是通吃了。 至於,為何這沒有 compiler error ? 那是因為一個「字串」也是一個有效的 EXPR (expression / 算式)。其實 grep 也可以這樣用: # 找出 @array 中所有正好是 "foo" 的值 @result = grep $_ eq "foo", @array; # 找出 5 < $_ < 10 的值 @result = grep 5 < $_ && $_ < 10, @array; 這部份應該是有點舊的語法,而在 Perl5 中一直支援舊的語法。因此, 單單一個字串並沒有 compile error。不過我個人認為起碼可以有個 warning。 讀起來比較不討人厭的寫法,現在是用 block: @result = grep { 5 < $_ && $_ < 10 } @array; 猛一看好像沒太大差別?不過多一組大括號確實有助於閱讀。 : b. regular expression 裡 我若打 $str = "/aaa/bbb{2}/ccc[0]/"; : 然後在某處用到 =~m/$str/ 到底意義是甚麼? : 是 m//aaa/bbb{2}/ccc[0]// : 還是 m/aaa/bbb\{2\}/ccc\[0\]/ : 可不可以幫我解答一下? 尤其是最前面和最後的/ /需要跳脫字元嗎? 建議您在與到 $str 中有 "/" 時,把 m// 換個括號,像 m{} 就完全沒有 解讀上的困擾。 $x =~ m/\/aaa\/bbb{2}\/ccc[0]\//; 這等價於 $x =~ m{/aaa/bbb{2}/ccc[0]/}; 另一方面,以下後三行也是等價的: $str = "/aaa/bbb{2}/ccc[0]/"; $x =~ m/$str/; $x =~ m/\/aaa\/bbb\{2\}\/ccc\[0\]\//; $x =~ m{/aaa/bbb\{2\}/ccc\[0\]/}; 希望這例能幫助您理解到在 regular expression 中內插字串的狀態。 : c. 請問關於$_,有沒有一個比較統一的規則可以解釋 : 我目前只知道 while(<INFILE>) { : print $_; : } : 或是 print $_ foreach(@array); : 但常常寫錯 不知道為什麼 請問$_的scope在哪裡 : 有哪些function或操作 會implicit的用到$_?? : 感謝大大 ~~ $_ 是全域變數。`perlfoc perlfunc` 中列出的內建函式大部份都 會去用 $_ 。 -- Scheme teaches us that : "An integer is a rational is a real is a complex number is a number." -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.32.222.155

07/24 08:07, , 1F
推!
07/24 08:07, 1F

07/24 16:26, , 2F
頸推!
07/24 16:26, 2F

07/30 11:59, , 3F
臏숡!看不太懂但是我會好好研究
07/30 11:59, 3F

07/30 12:04, , 4F
謝謝您 太詳細了
07/30 12:04, 4F
文章代碼(AID): #1CITVIHE (Perl)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):
文章代碼(AID): #1CITVIHE (Perl)