2013-07-19 64 views
3

我在讀一個regex group matching問題,我看到有從正則表達式表達,即參比捕獲基團兩種方式,Ruby - 提取正則表達式捕獲組的最佳方式?

  1. Match字符串的方法例如string.match(/(^.*)(:)(.*)/i).captures
  2. 的Perl式的捕獲組變量,例如從if match =~ /(^.*)(:)(.*)/i
  3. 更新獲得$ 1,$ 2等:正如0xCAFEBABE提到有第三種選擇太 - last_match方法

哪個更好?有了1),爲了安全起見,你將不得不使用if語句來防範nils,爲什麼不直接提取信息?而不是第二步調用字符串捕獲方法。所以選項2)對我來說更加方便。

+2

甚至有第三個:[RegExp.last_match](http://www.ruby-doc.org/core-2.0/Regexp.html#method-c-last_match)。哦,timtowtdi。 – 0xCAFEBABE

+0

沒有'Match'類。你可能是指'MatchData'類。 – sawa

+0

@sawa我不好,這是一個字符串方法,我已經更新了這個問題。 –

回答

3

對於簡單的任務,直接訪問僞變量$1等等可能更簡單,但是當事情變得複雜時,通過MatchData實例訪問事物是(幾乎)唯一的方法。

例如,假設你正在做的嵌套gsub

string1.gsub(regex1) do |string2| 
    string2.gsub(regex2) do 
    ... # Impossible/difficult to refer to match data of outer loop 
    end 
end 

在內部循環,假設要指的是捕獲的組外gsub的。調用$1,$2等將不會給出正確的結果,因爲最後的匹配數據已通過執行內部gsub循環而改變。這將是錯誤的來源。

,有必要通過比賽數據指捕獲組:

string1.gsub(regex1) do |string2| 
    m1 = $~ 
    string2.gsub(regex2) do 
    m2 = $~ 
    ... # match data of the outer loop can be accessed via `m1`. 
     # match data of the inner loop can be accessed via `m2`. 
    end 
end 

總之,如果你想爲簡單的任務,做短線的hackish東西,你可以使用僞變量。如果你想保持你的代碼更加結構化和可擴展性,你應該通過匹配數據訪問數據。