为什么=〜运算符有时只会产生副作用?

时间:2011-05-25 12:32:53

标签: ruby regex pattern-matching irb oniguruma

我注意到Ruby / Oniguruma的副作用只出现在4个看似等效的陈述中的1个中。为什么变量day009中定义,而不在003005007中定义?

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中的行为。

2 个答案:

答案 0 :(得分:13)

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

但是,当您致电/(?<day>\d\d):(?<mon>\d\d)/ =~ "24:12"时,实际上是致电Regexp#=~

正如文件所说

  

if =〜与regexp文字一起使用   使用命名捕获,捕获字符串   (或零)被分配到本地   由捕获名称命名的变量。

003

怎么样?
  

如果是,则不会发生分配   regexp不是文字。

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

  

如果是,则不会发生分配   regexp位于右侧。
  “x = y”=〜   /(?<lhs>\w+)\s*=\s*(?<rhs>\w+)/
  p   lhs,rhs #undefined local variable

答案 1 :(得分:1)

我认为003不受支持,因为它在Rubyland中是一个完整的Regexp对象,可能有重写的方法等。这使得分配的本地人的范围变得更加复杂。