match, text, number = *"foobar 123".match(/([A-z]*) ([0-9]*)/)
我知道这是在做某种正则表达式匹配,但是 splat 在这里扮演什么角色,有没有办法在没有 splat 的情况下做到这一点,所以它不那么混乱?
splat 将正则表达式匹配结果(MatchData
包含三组:整个模式、字母和数字)分解为三个变量。所以我们最终得到:
match = "foobar 123"
text = "foobar"
number = "123"
如果没有 splat,则只有一个结果(the MatchData
),因此 Ruby 不知道如何将其分配给三个单独的变量。
MatchData的文档中有一个很好的解释:
因为在扩展 *variable 时会调用 to_a,所以有一个有用的分配快捷方式来提取匹配的字段。这比直接访问字段稍慢(因为生成了中间数组)。
all,f1,f2,f3 = *(/(.)(.)(\d+)(\d)/.match("THX1138.")) all #=> "HX1138" f1 #=> "H" f2 #=> "X" f3 #=> "113"
有没有办法在没有 splat 的情况下做到这一点,所以它不那么混乱?
由于与它的操作数a,b = [c,d]
相同,并且当它不是数组时a,b = *[c,d]
splat 调用您可以简单地显式调用 to_a 而不需要 splat:to_a
match, text, number = "foobar 123".match(/([A-z]*) ([0-9]*)/).to_a
不知道这是否不那么令人困惑,但它是无懈可击的。
String.match 返回一个 MatchData 对象,其中包含正则表达式的所有匹配项。splat 运算符拆分此对象并分别返回所有匹配项。
如果你只是跑
"foobar 123".match(/([A-z]*) ([0-9]*)/)
在 irb 中,您可以看到 MatchData 对象,其中收集了匹配项。
MatchData 是一个特殊变量,出于所有意图和目的,它是一个数组(某种),因此您实际上也可以这样做:
match, text, number = "foobar 123".match(/([A-z]*) ([0-9]*)/)[0..2]