12

我注意到 Ruby/Oniguruma 中的副作用仅出现在 4 个看似等效的语句中的 1 个中。为什么变量day定义在009, 而不是003, 005or 007

irb(main):001:0> r = /(?<day>\d\d):(?<mon>\d\d)/
=> /(?<day>\d\d):(?<mon>\d\d)/

irb(main):002:0> r =~ "24:12"
=> 0
irb(main):003:0> day
NameError: undefined local variable or method `day' 

irb(main):004:0> "24:12" =~ r
=> 0
irb(main):005:0> day
NameError: undefined local variable or method `day'


irb(main):006:0> "24:12" =~ /(?<day>\d\d):(?<mon>\d\d)/
=> 0
irb(main):007:0> day
NameError: undefined local variable or method `day'


irb(main):008:0> /(?<day>\d\d):(?<mon>\d\d)/ =~ "24:12"
=> 0
irb(main):009:0> day
=> "24"

nb#1:在所有四种情况下,它都是相同的正则表达式和相同的字符串。

nb#2:我已经验证了 MS Windows 和 Ubuntu Linux 中的行为。

4

2 回答 2

13

当你打电话时,"24:12" =~ r你实际上打电话"24:12".=~(r)。因此,String#=~只返回匹配开始的位置,如果没有匹配则返回 nil。

但是当你打电话时,/(?<day>\d\d):(?<mon>\d\d)/ =~ "24:12"你实际上是在调用Regexp#=~

正如文件所说

如果 =~ 与带有命名捕获的正则表达式文字一起使用,则捕获的字符串(或 nil)将分配给由捕获名称命名的局部变量。

怎么样003

如果正则表达式不是文字,则不会发生赋值。

   re = /(?<lhs>\w+)\s*=\s*(?<rhs>\w+)/
   re =~ "  x = y  "
   p lhs    # undefined local variable
   p rhs    # undefined local variable

如果将正则表达式放在右侧,则不会发生分配。
" x = y " =~ /(?<lhs>\w+)\s*=\s*(?<rhs>\w+)/
p lhs, rhs # 未定义的局部变量

于 2011-05-25T12:49:31.890 回答
1

我相信 003 不受支持,因为当时它是 Rubyland 中成熟的 Regexp 对象,可能带有重写的方法等。这使得分配的本地人的范围更加复杂。

于 2011-05-25T13:52:27.670 回答