2017-10-10 71 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'。等等。