如果我运行这个代码:
"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缓存是什么吗?
发布于 2017-10-10 02:28:30
我认为这是因为$1实际上是对在处理的最后一个正则表达式中发现的第一个捕获组的全局引用:Ruby2.4文档。因此,在您的例子中,您可能已经测试了正则表达式,并匹配了"5.60“。下面是我在ruby2.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"发布于 2017-10-10 02:27:12
您的代码没有真正的意义,它也没有做您认为它做的事情。
$1是一个全局变量,所以在调用gsub之前,第一个gsub将用$1中的任何内容替换匹配的模式。这是:
"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'。诸若此类。
https://stackoverflow.com/questions/46657536
复制相似问题