2009-09-21 94 views
3
match, text, number = *"foobar 123".match(/([A-z]*) ([0-9]*)/) 

我知道這是做某種正則表達式匹配,但是splat在這裏扮演什麼角色,並且有沒有一種方法可以在沒有圖示的情況下執行此操作,因此它不那麼令人困惑?什麼是splat在這裏做?

+0

哪個splat?在你的例子中有三個。 – shoover 2009-09-21 18:50:20

+1

shoover:你確定嗎?如果你的意思是'[A-Z] *'和'[0-9] *',那麼它們不是splats - 它們是正則表達式的一部分。 – 2009-09-21 19:09:14

回答

3

有沒有辦法做到這一點沒有圖示,所以它不那麼混亂?

由於a,b = [c,d]相同a,b = *[c,d]和圖示呼籲to_a其操作時,它不是一個數組,你可以簡單地調用to_a明確且不需要圖示:

match, text, number = "foobar 123".match(/([A-z]*) ([0-9]*)/).to_a 

不知道這是否是不那麼令人困惑,但它是無污點的。

0

String.match返回MatchData對象,其中包含正則表達式的所有匹配項。 splat運算符分割此對象並分別返回所有匹配項。

如果你只是在IRB運行

"foobar 123".match(/([A-z]*) ([0-9]*)/) 

,你可以看到MatchData對象,與收集的匹配。

5

splat將正則表達式匹配結果(MatchData分爲三組:整體模式,字母和數字)分解爲三個變量。因此,我們結了:

match = "foobar 123" 
text = "foobar" 
number = "123" 

沒有圖示,有好多隻能是一個結果(MatchData),因此Ruby不知道如何把它分配給了三個獨立的變量。

3

有一個在documentation for MatchData一個很好的解釋:

由於擴大 *變量時to_a被調用時,有用於提取匹配 領域有用的任務快捷方式。這比直接訪問字段的 稍慢(因爲生成了 中間數組)。

all,f1,f2,f3 = *(/(.)(.)(\d+)(\d)/.match("THX1138.")) 
    all #=> "HX1138" 
    f1 #=> "H" 
    f2 #=> "X" 
    f3 #=> "113" 
0

MatchData是一個特殊的變量,對所有意圖和目的陣列(種),所以你實際上可以做到這一點還有:

match, text, number = "foobar 123".match(/([A-z]*) ([0-9]*)/)[0..2] 

Learn more about the special variable MatchData

+0

它是一個類,而不是一個變量(從技術上講,它是一個指向類的常量,但String,Array等也是如此)並且沒有什麼特別之處。您可以在MatchData實例上調用'[]',因爲它定義了[]',並且可以在其上使用splat運算符,因爲它定義了'to_a'。 – sepp2k 2009-09-21 20:35:14