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

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

4

5 回答 5

5

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

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

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

于 2009-09-21T18:50:45.497 回答
3

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

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

   all,f1,f2,f3 = *(/(.)(.)(\d+)(\d)/.match("THX1138."))
   all   #=> "HX1138"
   f1    #=> "H"
   f2    #=> "X"
   f3    #=> "113"
于 2009-09-21T18:51:22.780 回答
3

有没有办法在没有 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

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

于 2009-09-21T20:38:32.857 回答
0

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

如果你只是跑

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

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

于 2009-09-21T18:50:36.217 回答
0

MatchData 是一个特殊变量,出于所有意图和目的,它是一个数组(某种),因此您实际上也可以这样做:

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

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

于 2009-09-21T19:24:22.700 回答