【问题标题】:Difference in a one line block code between === and match?=== 和 match 之间的一行代码的区别?
【发布时间】:2020-06-28 07:07:54
【问题描述】:

我有以下代码示例来检查数组中的某些元素是否匹配给定的正则表达式:

["SELECT column1, column2 FROM table1, table2 WHERE column2='value';",
 "SELECT * FROM Customers WHERE Last_Name='Smith';",
 "SELECT * FROM Friends"].none? { |sql| /WHERE/i.match?(sql) }
# false

如您所见,我使用match? 只是为了查看接收者和方法参数是否匹配。正如文档中所述,我对使用 match 的优点不感兴趣:

返回真或假表示正则表达式是否匹配不更新$~等相关变量。如果第二个参数存在,它指定字符串中开始搜索的位置。

所以,我可以轻松地使用===

["SELECT column1, column2 FROM table1, table2 WHERE column2='value';",
 "SELECT * FROM Customers WHERE Last_Name='Smith';",
 "SELECT * FROM Friends"].none? { |sql| /WHERE/ === sql }
# false

返回的结果是一样的。也许对这种事情使用大小写相等并不常见,但这允许我将正则表达式作为无传递?参数,并避免打开块,因为我使用的是 Ruby 2.5+:

array.none?(/WHERE/) # false

并且工作方式几乎相同(对于每个可枚举的谓词方法也一样):

array.any? { |sql| /WHERE/i.match?(sql) } # true
array.any? { |sql| /WHERE/ === sql } # true
array.any?(/WHERE/) # true

所以,我的问题是;考虑到这些情况使用=== 来检查数组中的每个字符串实例是否与给定的正则表达式匹配,对我来说会不会一样?如果是这样,我可以将它们全部替换为仅将正则表达式作为方法 (none?, any?) 参数传递。

【问题讨论】:

  • 提示:; 分隔符仅用于交互式 SQL shell,而不用于 Ruby 代码。

标签: ruby


【解决方案1】:

Regexp#=== 存在的原因主要是用于case 语句,例如:

case (str)
when /WHERE/i
  # ...
end

在内部调用=== 来检查匹配项。这就是为什么你可以做很多非常疯狂的事情,比如:

case (str)
when String
when 0..20
when 'example'
when /text/
end

除此之外,这一切都归功于=== 比较。

值得注意的是,它并不打算像您一样使用。 match? 非常清楚地传达了您的意图,但 === 可能会令人困惑,因为它看起来很像表示“比较”的 ==,但这不是普通的比较。

好消息是 Ruby 允许直接将正则表达式与 any? 一起使用,也可以使用以下替代方法:

[
   "SELECT column1, column2 FROM table1, table2 WHERE column2='value';",
   "SELECT * FROM Customers WHERE Last_Name='Smith';",
   "SELECT * FROM Friends"
].grep(/WHERE/i).any?

grep 方法可以采用字符串或正则表达式。

grep 方法非常适合过滤,但如果您只想知道它们是否匹配,它的效率不如any?,所以我会改用它。

【讨论】:

  • 非常感谢塔德曼。 grep 是否也在后台使用 ===grepany? 的使用会以某种方式替换吗?
  • 我不认为grep 可以,就像any? 一样,它可以接受字符串或正则表达式。
  • 当你想知道所有匹配的条目时,我建议使用grep,但如果你不关心哪个,至少有any?一。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-22
  • 1970-01-01
  • 1970-01-01
  • 2010-10-25
  • 1970-01-01
  • 2018-08-30
  • 1970-01-01
相关资源
最近更新 更多