如果字符串包含数组中包含的一个或多个值,请替换它

时间:2015-11-16 04:41:43

标签: ruby string substitution

我有一个Ruby字符串,例如:"blue green yellow dog cat mouse alpha beta"

我想替换:

  • 带有"color"
  • 一词的颜色名称
  • 带有"animal"
  • 字样的动物名称
  • 希腊字母名称,单词"letter"

换句话说,在我上面的例子中,我希望新字符串为:

"color animal letter"

而不是

"color color color animal animal animal letter letter"

我想出了以下方法:

def convert_string(string)
    if ["cat", "dog", "mouse"].include? key.to_s
      return "animal"
    end
    if ["blue", "yellow", "green"].include? key.to_s
      return "color"
    end
    if ["alpha", "beta"].include? key.to_s
      return "letter"
    end
    return key
end

如何改进我的方法以达到我的需要?

2 个答案:

答案 0 :(得分:2)

您可以使用gsub

str = "blue green yellow dog cat mouse alpha beta"

str.gsub(/(cat|dog|mouse)/, 'animal')
   .gsub(/(blue|yellow|green)/, 'color')
   .gsub(/(alpha|beta)/, 'letter')
   .split.uniq.join ' '

答案 1 :(得分:2)

假设:

str = "gamma blue green yellow dog cat mouse alpha beta"

请注意,str与问题中给出的示例略有不同。

我假设您想要用“颜色”(或“动物”或“字母”)替换字符串中的每一行颜色(或动物或字母)。

这有两种方法。

<强>#1

这使用Enumerable#chunkObject#itself。后者在第2.2节中介绍。对于早期版本,请写...chunk { |s| s }...

str.split.map do |word|
  case word
  when "blue", "green", "yellow"
    "color"
  when "dog", "cat", "mouse"
    "animal"
  when "alpha", "beta", "gamma"
    "letter"
  end
end.chunk(&:itself).map(&:first).join(' ')
  #=> "letter color animal letter"

map返回:

#=> ["letter", "color", "color", "color", "animal",
#    "animal", "animal", "letter", "letter"] 

然后chunk编辑。将此数组表示为arr,是分块的替代方法:

arr.each_with_object([]) { |w,a| a << w if a.empty? || w != a.last }

#2

COLOR  = "color"
ANIMAL = "animal"
LETTER = "letter"

h = { COLOR  => %w{ blue green yellow },      
      ANIMAL => %w{ dog cat mouse },
      LETTER => %w{ alpha beta gamma } }.
      each_with_object({}) { |(k,v), h| v.each { |item| h[item] = k } }
 #=> {"blue"=>"color", "green"=>"color", "yellow"=>"color",
 #    "dog"=>"animal", "cat"=>"animal", "mouse"=>"animal",
 #    "alpha"=>"letter", "beta"=>"letter", "gamma"=>"letter"}

r = /
    \b        # match a word break
    (\w+)     # match a word in capture group 1
    (?:\s\1)+ # match one or more copies of the matched word, each preceded by a space
    \b        # match a word break
    /x        # extended or free-spacing mode

str.gsub(/\w+/,h).gsub(r,'\1')
  #=> "letter color animal letter"

str.split.map { |word| h[word] }.chunk(&:itself).map(&:first).join(' ')
  #=> "letter color animal letter"