2011-03-15 35 views
10

我試圖與紅寶石1.9.2p136(2010-12-25)[I386-的mingw32]這個例子myhash = {/(\d+)/ => "hello"}
預期它不工作(編輯:事實證明,我期待它不應該工作):紅寶石1.9正則表達式作爲散列鍵

irb(main):004:0> myhash = {/(\d+)/ => "hello"} 
=> {/(\d+)/=>"Hello"} 
irb(main):005:0> myhash[2222] 
=> nil 
irb(main):006:0> myhash["2222"] 
=> nil 

Rubular這是對ruby1.8.7的regex作品。
我錯過了什麼?

+0

'myhash'與'hash'? – gnab 2011-03-15 11:35:33

+0

@gnab - 很好的發現。但不幸的是,這不是問題 – 2011-03-15 11:36:46

+1

我認爲你必須迭代散列並進行正常匹配。它不會很快。 – 2011-03-15 11:56:24

回答

9

沒有一些額外的代碼就無法工作,因爲它是將Regexp對象與Integer或String對象進行比較。他們不會是價值平等,也不是身份平等。它們會匹配,但需要對Hash類代碼進行更改。

irb(main):001:0> /(\d+)/.class 
=> Regexp 
irb(main):002:0> 2222.class 
=> Fixnum 
irb(main):003:0> '2222'.class 
=> String 
irb(main):004:0> /(\d+)/==2222 
=> false 
irb(main):007:0> /(\d+)/=='2222' 
=> false 
irb(main):009:0> /(\d+)/.equal?'2222' 
=> false 
irb(main):010:0> /(\d+)/.equal?2222 
=> false 

,你將不得不遍歷哈希和使用=〜在這樣的:

hash.each do |k,v|  
    unless (k=~whatever.to_s).nil? 
    puts v 
    end 
end 

或改變哈希類嘗試=〜除了正常的匹配條件。 (我認爲最後一個選項很難,在哈希類似乎有很多C代碼)

1

我從來沒有想過使用正則表達式作爲散列鍵。我真的不確定這是否應該起作用,也不知道它應該如何工作。

在任何情況下,兩種思想:

  1. 在你試圖查找項目,您使用hash,但哈希名爲myhash
  2. 如果我玩它,我得到這些結果:

    hektor ~ ❯❯ irb 
    >> myhash = {/(\d+)/ => "hello"} 
    => {/(\d+)/=>"hello"} 
    >> myhash['2222'] 
    => nil 
    >> myhash[2222] 
    => nil 
    >> myhash[/(\d+)/] 
    => "hello" 
    

這是使用Ruby 1.9.2-P180。

好,檢查和這裏的什麼作品:

myhash = {/foo/ => "hello"} 
myhash[/foo/] # => "hello" 

查找是關鍵,關鍵是一個正則表達式,而不是正則表達式的許多潛在的比賽之一。

+0

@Telemachus - yeap myhash&hash是我的錯字。它看起來像ruby並不真正把/(\ d +)/當作一個正則表達式。 – 2011-03-15 11:45:24

+0

@Telemachus - 我遇到這個SO帖子http://stackoverflow.com/questions/2082457/ruby-gsub-problem-when-using-backreference-and-hashes。它看起來應該起作用。 – 2011-03-15 11:48:19

+0

你鏈接的帖子需要一個迭代器和一個調用gsub的函數來解釋正則表達式。在你的情況下,你正試圖用整數和字符串分別比較正則表達式對象... – Jean 2011-03-15 11:55:33

10

你是否正在尋找此行爲?

myhash = Hash.new{|h,k| h[k] = 'hello' if k =~ /(\d+)/} 

p myhash['aaa'] #=> nil 
p myhash #=> {} 
p myhash['1234'] #=>" hello" 
p myhash #=> {"1234"=>"hello"} 
3

你可以把吉恩的答案在default_proc

MAP = { 
    /1/ => "one", 
    /2/ => "two", 
    /\d/ => "number" 
} 

MAP.default_proc = lambda do |hash, lookup| 
    hash.each_pair do |key, value| 
    return value if key =~ lookup 
    end 
    return nil 
end 

p MAP["2"] #=> "two" 
p MAP[44] #=> "number"