如何在不使用正则表达式的情况下匹配ruby中的字符串?

时间:2012-11-02 20:42:56

标签: ruby

目前,我正在这样做:

(in initialize)
 @all = Stuff.all.each.map {|t| t.reference_date }
 @uniques = @all.uniq



results = []
@uniques.each do |k|
  i = 0
  @all.each do |x|
    i += 1 if x =~ %r{#{x}}
  end
  results << [k, i]
end

那没关系。它会起作用。但我喜欢在可以的时候避免使用正则表达式。我觉得他们有点feo。那是丑陋的西班牙语。

EDIT-- 实际上,这是行不通的,因为当日期对象放在字符串内部(作为变量,这里)时,ruby将日期作为2012-03-31的编号格式“放置”,但它实际上是一个日期对象,所以这个工作:

if x.month == k.month && x.day == k.day
  i += 1
end

5 个答案:

答案 0 :(得分:2)

你可以只用一行(如果我当然是正确的话):

array = %w(a b c d a b d f t z z w w)
# => ["a", "b", "c", "d", "a", "b", "d", "f", "t", "z", "z", "w", "w"]
array.uniq.map{|i|[i, array.count(i)]}
# => [["a", 2], ["b", 2], ["c", 1], ["d", 2], ["f", 1], ["t", 1], ["z", 2], ["w", 2]]

答案 1 :(得分:1)

results = Hash.new(0)
@all.each{|t| results[t] += 1}
# stop here if a hash is good enough.
# if you want a nested array:
results = results.to_a

这是获取可枚举元素频率的标准方法。

答案 2 :(得分:1)

要避免正则表达式的外观,您可以使用Regexp.union动态构建它们。您可能想要这样做的原因是SPEED。构造良好的正则表达式比迭代列表更快,尤其是大型列表。并且,通过允许您的代码构建正则表达式,您不必维护一些丑陋(feo)的东西。

例如,这是我在不同的代码块中所做的事情:

words = %w[peer_address peer_port ssl ssl_protocol ssl_key_exchange ssl_cipher]
regex = /\b(?:#{ Regexp.union(words).source })\b/i
=> /\b(?:peer_address|peer_port|ssl|ssl_protocol|ssl_key_exchange|ssl_cipher)\b/i

这使维持正则表达式变得微不足道。并且,尝试使用该基准来查找文本中的子字符串以反对迭代,它会给您留下深刻的印象。

答案 3 :(得分:0)

如果通配符适合您,请尝试File.fnmatch

答案 4 :(得分:0)

从您的代码中我感觉您想获得每个reference_date的出现次数。通过直接使用ActiveRecord和SQL而不是拉动整个故事然后在Ruby中执行耗时的操作,可以更容易地实现这一点。

如果您使用的是Rails 2.x,您可以使用以下内容:

Stuff.find(:all, :select => "reference_date, COUNT(*)", :group => "reference_date")

或者如果您使用的是Rails 3,那么您可以将其简化为

Stuff.count(:group => "reference_date")