如果我運行
"Year 2010" =~ /([0-4]*)/;
print $1;
我得到空字符串。 但是
"Year 2010" =~ /([0-4]+)/;
print $1;
輸出「2010」。爲什麼?
如果我運行
"Year 2010" =~ /([0-4]*)/;
print $1;
我得到空字符串。 但是
"Year 2010" =~ /([0-4]+)/;
print $1;
輸出「2010」。爲什麼?
在第一個窗體的字符串「Year 2010」的開始處您會得到一個空匹配,因爲*會立即匹配0個數字。 +表單必須等到至少有一個數字在匹配之前。大概如果你可以通過全部第一種形式的比賽,你最終會發現2010 ...但可能只有在'e'之前發現另一個空比賽之後,然後在'a'之前,等等。
太好了,謝謝! – alexanderkuk 2010-10-21 09:26:36
Kleene星形生成的超集也包含空字符串,所以是的,它會匹配Y,e,a,r,whitespace之前的空字符串,然後它會找到2010。 – 2010-10-21 09:37:44
第一個匹配開始處的零長度字符串(在Y
之前)並返回它。第二個搜索一個或多個數字並等待,直至找到2010
。
第一個正則表達式成功匹配字符串開頭的零個數字,這會導致捕獲空字符串。
第二個正則表達式匹配失敗在字符串的開頭,但是當它達到2010
你也可以使用YAPE::Regex::Explain的正則表達式的解釋像它匹配
use YAPE::Regex::Explain;
print YAPE::Regex::Explain->new('([0-4]*)')->explain();
print YAPE::Regex::Explain->new('([0-4]+)')->explain();
輸出:
The regular expression:
(?-imsx:([0-4]*))
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):
----------------------------------------------------------------------
( group and capture to \1:
----------------------------------------------------------------------
[0-4]* any character of: '0' to '4' (0 or more
times (matching the most amount
possible))
----------------------------------------------------------------------
) end of \1
----------------------------------------------------------------------
) end of grouping
----------------------------------------------------------------------
The regular expression:
(?-imsx:([0-4]+))
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):
----------------------------------------------------------------------
( group and capture to \1:
----------------------------------------------------------------------
[0-4]+ any character of: '0' to '4' (1 or more
times (matching the most amount
possible))
----------------------------------------------------------------------
) end of \1
----------------------------------------------------------------------
) end of grouping
----------------------------------------------------------------------
星形符號試圖基本上匹配給定的0或多個符號(理論上,集合{X,Y} *由空字符串和所有可能的由x和y組成的有限序列),因此,它將在字符串的開始處精確匹配零個字符(空字符串),在第一個字符之後零個字符,在第二個字符之後零個字符等。然後最終它會找到2並匹配整個2010年。
加號符號與給定集合中的一個或多個字符匹配({x,y} +由x和y組成的所有可能的有限序列,沒有空字符串,而不是{x,y} *)。所以第一個符合的匹配字符是2,然後檢查下一個0,然後是1,然後是0,然後句子結束,因此找到的組看起來像'2010'。
這是正式表達式的標準行爲,在正式語言理論中定義。我強烈建議學習正則表達式有點理論,它不能傷害,但可以幫助:)
爲了使您的第一個RE匹配,使用錨「$」:
"Year 2010" =~ /([0-4]*)$/;
print $1;
我們在學習Perl中將此作爲一個技巧性問題。可以匹配零個字符的任何正則表達式匹配零個字符。
Perl正則表達式引擎匹配最左邊的最長匹配,最左邊的部分最先匹配。不過,並非所有的正則表達式引擎都可以這樣工作。如果你想要所有的技術細節,請閱讀掌握正則表達式,它解釋了正則表達式引擎如何工作並找到匹配。
有什麼奇怪的是'/ \ s([0-4] *)/'不具有相同的快捷行爲。它沒有說「我在空間的末尾匹配了零長度的字符串,在這裏你去。」 – Axeman 2010-10-21 14:12:55
@Axeman,那是因爲'*'是貪婪的。數字在那裏,所以它抓住了他們。如果您與「2010年度」匹配,則「$ 1」將是第一個空格後面的零長度字符串。 – cjm 2010-10-21 16:08:36