【问题标题】:Check if a string includes any of the keys in a hash and return the value of the key it contains检查字符串是否包含哈希中的任何键并返回它包含的键的值
【发布时间】:2015-06-28 01:32:42
【问题描述】:

我有一个包含多个键的散列和一个不包含散列键或其中一个键的字符串。

h = {"k1"=>"v1", "k2"=>"v2", "k3"=>"v3"}
s = "this is an example string that might occur with a key somewhere in the string k1(with special characters like (^&*$#@!^&&*))"

检查s 是否包含h 中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?

例如,对于上述hs 的示例,输出应为v1

编辑:只有字符串是用户定义的。哈希值始终相同。

【问题讨论】:

    标签: ruby string hash


    【解决方案1】:

    我觉得这种方式可读:

    hash_key_in_s = s[Regexp.union(h.keys)]
    p h[hash_key_in_s] #=> "v1"
    

    或者在一行中:

    p h.fetch s[Regexp.union(h.keys)] #=> "v1"
    

    这是一个不使用正则表达式的版本:

    p h.fetch( h.keys.find{|key|s[key]} ) #=> "v1"
    

    【讨论】:

    • 我之前不知何故错过了你的答案。太棒了!
    【解决方案2】:

    从哈希 h 键和字符串中的 match 创建一个正则表达式:

    h[s.match(/#{h.keys.join('|')}/).to_s]
    # => "v1"
    

    或者正如 Amadan 建议使用 Regexp#escape 以确保安全:

    h[s.match(/#{h.keys.map(&Regexp.method(:escape)).join('|')}/).to_s]
    # => "v1"
    

    如果 String s 是均匀分布的,我们也可以这样做:

    s =  "this is an example string that might occur with a key somewhere in the string k1 (with special characters like (^&*$\#@!^&&*))"
    h[(s.split & h.keys).first]
    # => "v1"
    

    【讨论】:

    • h.keys.map(&Regexp.method(:escape)).join('|') 为了安全起见,除非键实际上是正则表达式。
    • 你应该先获取key,然后如果key不是nil,则获取h[key],以防字符串不包含任何哈希键。而不是使用join(这很好),您可以像这样执行第一步:key = s[Regexp.union(h.keys.map(&Regexp.method(:escape)))] => "k1"。还有一件事:很好的答案!
    • 感谢 Cary 一如既往的宝贵建议 :)
    • 感谢@Amadan 指出这一点,并很抱歉之前没有注意到这一点,但在这种情况下不需要escape,因为只有字符串是用户定义的。另外@shivam,您可以将第三个选项更改为h[(s.split(/[\s(]/) & h.keys).first],以便它适用于示例字符串。
    猜你喜欢
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 2014-04-06
    • 2014-11-26
    • 2015-03-28
    • 2017-10-13
    • 2015-05-15
    • 1970-01-01
    相关资源
    最近更新 更多