问题描述
|
我注意到Ruby / Oniguruma的副作用仅出现在4个看似等效的语句中的1个中。为什么在
009
中定义变量day
,而在003
,005
或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中的行为。
解决方法
当您呼叫
\"24:12\" =~ r
时,您实际上会呼叫\"24:12\".=~(r)
。因此,String#=〜仅返回匹配开始的位置,如果没有匹配,则返回nil。
但是当您呼叫/(?<day>\\d\\d):(?<mon>\\d\\d)/ =~ \"24:12\"
时,您实际上呼叫了Regexp#=〜
正如文档所说
如果=〜与正则表达式文字一起使用
与命名捕获,捕获的字符串
(或nil)分配给本地
由捕获名称命名的变量。
003
呢:
如果
regexp不是文字。
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#未定义的局部变量
,我认为不支持003,因为它是当时Rubyland中一个完整的Regexp对象,可能带有重写的方法等。这使分配的本地人的范围变得更加复杂。