2012-11-22 83 views
1

在一個Perl/Tk的代碼,我發現了一個條件語句如下在Perl中,if(s/^ + //)的含義是什麼?

if (s/^\+//) 
{ 
    #do something 
} 
elsif (/^-/) 
{ 
    #do another thing 
} 

好像一些模式匹配已經完成。但我無法理解它。任何人都可以幫我理解這種模式匹配嗎?

+2

@Oded,該鏈接ISN這是我見過的最糟糕的Perl教程,但它比較老,使用一些過時的做法('-w' vs'warnings',prototypes)。我可能會推薦['perldoc perlretut'](http://p3rl.org/retut)。 –

+0

@JoelBerger - 夠公平的。這是谷歌第一次點擊。 – Oded

+3

@Oded,NP。 Perl教程的長久性是社區通過製作/突出更新的更好的教程來努力爭取的,並且警告關於老教師/壞教師的問題http://perl-tutorial.org/。在互聯網泡沫帶來很多糟糕的代碼之後,Perl得到了一個不好的名字,我們試圖一次性改進一個教程。 –

回答

11

它們都是正則表達式。您可以在perlreperlretut上閱讀。你可以在http://www.rubular.com上與他們玩。

它們都隱含地做了$_。你的代碼行可能有一個whileforeach而沒有循環變量。在那種情況下,$_成爲該循環變量。它可能包含正在讀取的文件的當前行。

  1. 如果$_當前值包含+(加號)作爲字符串,#do somehting開始的第一個字符。
  2. 否則,如果它包含-(負號),#do another thing

在案例1中,它也將該符號替換爲+(即刪除它)。但它不會刪除2中的-


讓我們看看YAPE::Regex::Explain的解釋。

use YAPE::Regex::Explain; 
print YAPE::Regex::Explain->new(qr/^\+/)->explain(); 

這是它。在我們的案例中不是很有幫助,但是卻是一個不錯的工具。請注意,(?-imsx)部分是Perl暗示的默認東西。除非你改變它們,它們總是在那裏。

The regular expression: 

(?-imsx:^\+) 

matches as follows: 

NODE      EXPLANATION 
---------------------------------------------------------------------- 
(?-imsx:     group, but do not capture (case-sensitive) 
         (with^and $ matching normally) (with . not 
         matching \n) (matching whitespace and # 
         normally): 
---------------------------------------------------------------------- 
^      the beginning of the string 
---------------------------------------------------------------------- 
    \+      '+' 
---------------------------------------------------------------------- 
)      end of grouping 
---------------------------------------------------------------------- 

更新:作爲米科L的評論中指出,應重構也許/更改這段代碼。雖然它可能做到了它應有的目標,但我相信這會讓它更具可讀性。誰寫的顯然不關心你作爲後來的維護者。我建議你這樣做。您可以將其更改爲:

# look at the content of $_ (current line?) 
if (s/^\+//) 
{ 
    # the line starts with a + sign, 
    # which we remove! 

    #do something 
} 
elsif (m/^-/) 
{ 
    # the line starts witha - sign 
    # we do NOT remove the - sign! 

    #do another thing 
} 
+1

您的分析是點亮的。我會補充說OP應該考慮重構這段代碼,以便替換更明顯。以現在寫的方式錯過它很容易。甚至簡單地去'if(/^\ + /){$ _ =〜s/^ \ + //; #做點什麼}'會有相當大的幫助。 –

+0

@MikkoL我同意並添加了這些建議。我不同意明確使用'$ _',但這是我個人的偏好。謝謝。 – simbabque

+1

Downvoter,你是否喜歡評論我如何改進我的帖子? – simbabque

5

這些是正則表達式,用於模式匹配和替換。

你應該在概念讀了,但你的問題:

s/^\+// 

如果字符串開始有加,除去加(以下簡稱「s」表示「替代」),並返回true 。

/^-/ 

如果字符串以負號開頭,則爲true。

3

該代碼相當於

if ($_ =~ s/^\+//) { # s/// modifies $_ by default 
    #do something 
} 
elsif ($_ =~ m/^-/) { # m// searches $_ by default 
    #do another thing 
} 

s///m//是正則表達式報價狀運算符。你可以在perlop閱讀。

+2

這是一個非常好的(儘管很短)的答案。我不明白爲什麼它是downvoted。 – simbabque

+1

我沒有downvote,但我確定它是因爲,隱式變量在這裏沒有問題,而是替代模式本身。 –

2

其他答案給出了代碼如何工作的總結,但沒有太多的原因。以下是爲什麼可以使用這種邏輯的一個簡單例子。

#!/usr/bin/env perl 

use strict; 
use warnings; 

my $args = {}; 

for (@ARGV) { 
    if (s/^no//) { 
    $args->{$_} = 0; 
    } else { 
    $args->{$_} = 1; 
    } 
} 

use Data::Dumper; 
print Dumper $args; 

當你調用像

./test.pl hi nobye 

腳本你

$VAR1 = { 
      'hi' => 1, 
      'bye' => 0 
     }; 

的關鍵是字符串,但是如果它是由no前面,然後將其刪除(拿到鑰匙有問題),而是將值設置爲0

OP的例子有一點涉及,但遵循相同的邏輯。

  • 如果有+鑰匙啓動,刪除它,然後做一些
  • 如果有-鑰匙啓動,請不要刪除它,做別的事情
+0

@downvoter,關心評論? –

相關問題