splat在这做什么?

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

我知道这是在进行某种正则表达式匹配,但是splat在这里扮演什么角色,有没有办法在没有splat的情况下做到这一点,所以它不那么令人困惑?

有没有办法在没有splat的情况下做到这一点,所以它不那么令人困惑?

由于a,b = [c,d]a,b = *[c,d]相同a,b = *[c,d]并且splat在其操作数上调用to_a ,当它不是数组时,你可以简单地调用to_a而不需要splat:

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

不知道这是不是那么令人困惑,但它是无懈可击的。

splat将正则表达式匹配结果(具有三个组的MatchData :整个模式,字母和数字)分解为三个变量。 所以我们最终得到:

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

没有splat,只有一个结果( MatchData ),因此Ruby不知道如何将它分配给三个独立的变量。

MatchData的文档中有一个很好的解释:

因为在展开*变量时调用to_a,所以有一个有用的赋值快捷方式来提取匹配的字段。 这比直接访问字段稍慢(生成中间数组)。

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

String.match返回一个MatchData对象,该对象包含正则表达式的所有匹配项。 splat运算符拆分此对象并分别返回所有匹配项。

如果你只是跑

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

在irb中,您可以看到MatchData对象,并收集匹配项。

MatchData是一个特殊的变量,对于所有意图和目的而言,一个数组(种类),所以你实际上也可以这样做:

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

了解有关特殊变量MatchData的更多信息