2017-04-02 112 views
1

在「綜合Ruby編程過程'電子書,我面臨的一章,其中作者(喬丹·哈金斯)描述了它喜歡:Regexp.last_match - 爲什麼它有用?

「我們要嘗試的事情就是返回所有的整數值從句子」

而且他確實是這樣的:

string = "The quick 12 brown foxes jumped over 10 lazy dogs" 
p string.to_enum(:scan, /\d+/).map { Regexp.last_match } 

,並返回:

=> [#<MatchData "3">, #<MatchData "34">, #<MatchData "23">] 

我不知道爲什麼/時,這Regexp.last_match可以使用或不如說 - 爲什麼這樣是不是更有效率比:

p string.to_enum(:scan, /\d+/).map { |i| p i } 

此只輸出整數數組,似乎我作爲一個更有效的方法得到這些數字..

任何人也許能說明什麼可能是原因,筆者挑選Regesp.last_match

+1

你什麼建議爲* *的方式更好。全局可變狀態很醜。使用全局可變狀態*和*依賴實現細節?呸。有可能你應該選擇一個不同的電子書。 – Ryan

+0

謝謝你的迴應。接下來我要閱讀的內容是「Global mutable」:)如果它看起來太寬泛或無法回答,我會刪除這篇文章。關於那本書 - 其實很好,只是這部分有點奇怪...... –

+1

@Ryan 1.那些返回_different_東西,2.'Regexp.last_match'是_not_全局可變的。 – mudasobwa

回答

1

這是一個極好的技巧(閱讀:破解)。

string = "The quick 12 brown foxes jumped over 10 lazy dogs" 
p string.to_enum(:scan, /\d+/).map { Regexp.last_match } 

的事情是有一個從內到String#scanMatchDatayield情況下沒有簡便的方法。

p string.to_enum(:scan, /\d+/).map { |i| p i } 

使沒有太大意義,你可能是指:

p string.to_enum(:scan, /\d+/).map(&:itself) # or { |i| i } # or .to_a 

甚至

p string.scan(/\d+/) 

結果不同,雖然;後者返回,而前者是返回MatchData實例的方式。

+0

你爲什麼要'.map(&:itself)'? – Ryan

+0

@Ryan使代碼實際執行。 'to_enum'返回一個懶惰的枚舉器。 – mudasobwa

+0

那麼說'.to_a'的很長一段路? – Ryan

1

這裏有一個更詳細的,但可能是清潔的解決方案,如果你想MatchData實例的枚舉:

class String 
    def matches(regex) 
    position = 0 
    Enumerator.new do |yielder| 
     while match = regex.match(self, position) 
     yielder << match 
     position = match.end(0) 
     end 
    end 
    end 
end 

string = 'The quick 12 brown foxes jumped over 10 lazy dogs' 
p string.matches(/\d+/).to_a 
# [#<MatchData "12">, #<MatchData "10">] 
p (2**1000000).to_s.matches(/(\d)\1{5}/).first(2) 
# [#<MatchData "444444" 1:"4">, #<MatchData "888888" 1:"8">] 

如果你不想猴補丁String,你可以在Regex或獨立定義這個方法 - 單獨方法與stringregex作爲參數。

+0

謝謝@Eric,但我的元技能是在0或-1左右,所以我會更好地等待更有經驗的人來評判它:) p.s.猴子補丁意味着元編程(在這種情況下,覆蓋軟件)? :) –

+1

@ J.D。 :猴子打補丁意味着打開一個現有的類並修改它,例如通過定義一種新方法。這段代碼並不是真正的「元代碼」,更接近於你在Java或Python中編寫的內容。 –

相關問題