2017-10-10 76 views
0

如果我运行此代码:gsub缓存组?

"Retailer Staff $5.60".gsub(/.*\$(\d+(\.\d+)?).*/, $1) 
# => 5.60 

,然后我将值改为:

"Retailer Staff $5".gsub(/.*\$(\d+(\.\d+)?).*/, $1) 
# => 5.60 

答案停留在5.60。然后,如果我再次运行同一行,则会得到:

"Retailer Staff $5".gsub(/.*\$(\d+(\.\d+)?).*/, $1) 
# => 5 

发生了什么?为什么相同的代码运行两次会给出两个答案?是gsub缓存的东西?

+1

如果你正在寻找中提取值,可以考虑使用'scan',而不是'gsub'。 – tadman

+0

使用''零售商员工$ 5.60'来获取金额[/ \ $(\ d +(\。\ d +)?)/,1]' – Stefan

回答

2

我相信这一切,因为$1实际上是一个全球性的参考,最后的正则表达式找到的第一个捕获组已处理:ruby 2.4 docs。所以在你的情况下,你可能已经测试了正则表达式,并在“5.60”上匹配。这里是我的红宝石2.0跑了注解片段:

# Since no regex has executed yet $1 is nil 
irb(main):001:0> "Retailer Staff $5.60".gsub(/.*\$(\d+(\.\d+)?).*/, $1) 
TypeError: no implicit conversion of nil into String 
    from (irb):1:in 'gsub' 
    from (irb):1 
    from /usr/bin/irb:12:in '<main>' 
irb(main):002:0> "Retailer Staff $5.60".gsub(/.*\$(\d+(\.\d+)?).*/, 'some value') 
=> "some value" 
irb(main):003:0> $1 # Now we have executed a regex so $1 is set 
=> "5.60"    
irb(main):004:0> "Retailer Staff $5.60".gsub(/.*\$(\d+(\.\d+)?).*/, $1) 
=> "5.60" 
irb(main):005:0> $1 # This is still the same value because we matched the same string 
=> "5.60"    
irb(main):006:0> "Retailer Staff $5".gsub(/.*\$(\d+(\.\d+)?).*/, $1) 
=> "5.60" 
irb(main):007:0> $1 # Now we have matched the 5 so $1 has the new value 
=> "5"     
irb(main):008:0> "Retailer Staff $5".gsub(/.*\$(\d+(\.\d+)?).*/, $1) 
=> "5" 
irb(main):009:0> $1 
=> "5" 
2

你的代码没有意义,它不会做你认为它的作用。

$1是一个全局变量,所以第一个gsub将替换任何在$1之前你叫gsub匹配的模式。这:

"Retailer Staff $5.60".gsub(/.*\$(\d+(\.\d+)?).*/, $1) 

等同于:

confusion = $1 
"Retailer Staff $5.60".gsub(/.*\$(\d+(\.\d+)?).*/, confusion) 

当你真正的意思是说:

"Retailer Staff $5.60".gsub(/.*\$(\d+(\.\d+)?).*/) { $1 } 

使gsub可以屈服于块之前设置$1

一旦您了解了何时设置了$1以及何时进行了评估,那么其他一切都会落实到位。你的第一个gsub最终设置$1'5.60',然后下一个电话是说的只是一个过于复杂的方式:

"Retailer Staff $5".gsub(/.*\$(\d+(\.\d+)?).*/, '5.60') 

并将其设置$1'5'。等等。