检查字符串是否包含哈希表中的任何键,并返回它所包含的键的值。

5

我有一个哈希表有多个键,还有一个字符串,该字符串可能包含哈希表中的零个或一个键。

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

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

2个回答

5

我认为这种方法易读:

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"

我之前不知道你回答了。太好了! - Cary Swoveland

3

使用哈希表h的键创建正则表达式,并在字符串中进行匹配

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"

如果字符串 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"

4
为了安全起见,除非键实际上是正则表达式,否则可以将 h.keys.map(&Regexp.method(:escape)).join('|') 用于转义。 - Amadan
你应该先获取 key,然后在 key 不为 nil 的情况下获取 h[key],以防字符串不包含哈希表的任何键。而不是使用 join(这也可以),你可以像这样执行第一步:key = s[Regexp.union(h.keys.map(&Regexp.method(:escape)))] => "k1"。还有一件事:回答得很好! - Cary Swoveland
感谢Cary一如既往地提出宝贵的建议 :) - shivam
感谢 @Amadan 指出这一点,同时为没有早些时候注意到这一点而道歉,但在这种情况下不需要使用 escape,因为只有字符串是用户定义的。此外,@shivam,您可以将第三个选项更改为 h[(s.split(/[\s(]/) & h.keys).first],以便它适用于示例字符串。 - Sid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接