【问题标题】:How to see if string matches any regex keys in ruby hash如何查看字符串是否与 ruby​​ 哈希中的任何正则表达式键匹配
【发布时间】:2016-06-23 05:19:41
【问题描述】:

我有一个包含正则表达式键的 JSON 文件,其中包含基于发送消息的响应(例如,您好,Dragnflier!)。该文件包含如下值:

{
  "/hello/i" : "Why hello there!", 
  "/how are you.*dragnflier/i" : "I'm good thank you! How are you?"
}

我在我的 ruby​​ 程序开始时将它们加载到哈希中。有没有一种更有效的方法来查看消息是否与我的哈希中的任何正则表达式匹配,而不是使用所有键对其进行循环?我想获取键返回的值,而不是键列表或布尔值。

【问题讨论】:

  • 您没有发布代码。我们无法猜测我们看不到的代码的性能;-)
  • 正如问题所述,我只是在使用循环。循环通常是搜索数据的效率最低的方法。作为参考,它只是 commands.keys.each do |key| ....在我想要一个结果的情况下找到匹配项时打破循环,如果我想要多个结果则继续到最后。
  • 嗯,根据我的经验,使用代码的“描述”会导致很大的混乱和误解。您说“只是一个 foo”,但我可能会将其解释为“只是一个 FOO”。此外,要归档一个“基线”来测试所有想要回答这个问题的人,现在必须编写一个循环。为什么不这样做为我们工作? ;-)
  • 公平点。它更多地是一个笼统的问题,而不是一个具体的问题。

标签: ruby regex hash


【解决方案1】:

解决方案最终是,基于相反情况的其他答案:

val = myhash.keys.select {|key| message.to_s.match(key)}

【讨论】:

  • 如果您只想知道任何正则表达式是否匹配(而不关心哪个),请使用any? 而不是select。一旦找到匹配项,它将返回true,如果找不到匹配项,则返回false
  • 嗨,乔丹,我想从那个键中取回值,而不仅仅是看看是否存在。还是谢谢!
  • 顺便说一句,这个答案返回一个数组。使用detect 返回第一个匹配项。
  • 这不是问题的一部分。
  • 请注意 message.to_s.match(Regexp.new(key)) 可以简单地成为 message.to_s.match(key) b/c key 已经是 Regexp 对象,基于所使用的哈希
【解决方案2】:

是的,还有更有效的方法:

hash = {
  /hello/i => "Why hello there!", 
  /how are you.*dragnflier/i => "I'm good thank you! How are you?"
}
message =~ Regexp.union(hash.keys)

您说目标是检查“消息是否与我的哈希中的任何正则表达式匹配”。以上方法比您提出的解决方案更有效。

完成此初步检查后,人们可能会做任何她想做的事情来检测相应的密钥(此声明在我回答后出现在问题中。)这种方法将比仅对密钥进行暴力破解detect 更有效。

请注意,您提供的答案不正确,因为

Regexp.new '/foo/i'

变成

#⇒ /\/foo\/i/i 

而不是

#⇒ /foo/i

如你所料。

【讨论】:

  • 您好 mudasobwa,请查看我对问题的更改,我觉得场景澄清了我想要的值,而不仅仅是有与案例匹配的键。我已经修复了我的答案,我从哈希中的所有值中删除了 /i 以保存可读性并防止 /i 被遗忘时出现问题。在我的程序中的所有情况下,我总是希望它不区分大小写。
  • 漂亮的答案,但我认为它不是更有效。根据我的经验,即使在联合用于多个查询的情况下,联合也比简单地迭代正则表达式数组要慢。如果底层实现得到修复,您的代码可以而且应该更快。旁白:我倾向于从哈希值而不是exists?
猜你喜欢
  • 2016-06-07
  • 1970-01-01
  • 2017-02-18
  • 2014-02-20
  • 2011-07-08
  • 2016-02-11
  • 1970-01-01
  • 2021-12-18
  • 2023-01-30
相关资源
最近更新 更多