Ruby:将多个值插入字符串

时间:2014-02-14 02:34:03

标签: ruby string

假设我们有字符串"aaabbbccc",并希望使用String#insert将字符串转换为"aaa<strong>bbb</strong>ccc"。这是使用String#insert将多个值插入Ruby字符串的最佳方法,还是可以同时添加多个值:

string = "aaabbbccc"
opening_tag = '<strong>'
opening_index = 3
closing_tag = '</strong>'
closing_index = 6
string.insert(opening_index, opening_tag)
closing_index = 6 + opening_tag.length # I don't really like this
string.insert(closing_index, closing_tag)

有没有办法同时将多个子字符串插入到Ruby字符串中,因此结束标记不需要被添加的第一个子字符串的长度偏移?我想要这样一个班轮:

string.insert(3 => '<strong>', 6 => '</strong>') # => "aaa<strong>bbb</strong>ccc"

4 个答案:

答案 0 :(得分:3)

让我们玩得开心。 <怎么样

class String
  def splice h
    self.each_char.with_index.inject('') do |accum,(c,i)|
      accum + h.fetch(i,'') + c
    end  
  end  
end  

"aaabbbccc".splice(3=>"<strong>", 6=>"</strong>")
=> "aaa<strong>bbb</strong>ccc"

(你可以根据需要封装它,我只是喜欢搞乱内置插件,因为Ruby让我)

答案 1 :(得分:1)

如何从右向左插入?

string = "aaabbbccc"
string.insert(6, '</strong>')
string.insert(3, '<strong>')
string # => "aaa<strong>bbb</strong>ccc"

答案 2 :(得分:1)

opening_tag = '<strong>'
opening_index = 3
closing_tag = '</strong>'
closing_index = 6

string = "aaabbbccc"
string[opening_index...closing_index] = 
   opening_tag + string[opening_index...closing_index] + closing_tag
#=> "<strong>bbb</strong>"
string
#=> "aaa<strong>bbb</strong>ccc"

答案 3 :(得分:0)

如果您的字符串由三组连续字符组成,并且您希望在前两个组之间插入开始标记,并在最后两个组之间插入结束标记,无论每个组的大小如何,您都可以这样做:

def stuff_tags(str, tag)    
  str.scan(/((.)\2*)/)
    .map(&:first)
    .insert( 1, "<#{tag}>")
    .insert(-2, "<\/#{tag}>")
    .join
end

stuff_tags('aaabbbccc', 'strong')  #=> "aaa<strong>bbb</strong>ccc"
stuff_tags('aabbbbcccccc', 'weak') #=> "aa<weak>bbbb</weak>cccccc"

我将解释scan使用的正则表达式,但首先要说明如何对字符串'aaabbbccc'进行计算:

a = 'aaabbbccc'.scan(/((.)\2*)/)
  #=> [["aaa", "a"], ["bbb", "b"], ["ccc", "c"]]
b = a.map(&:first)
  #=> ["aaa", "bbb", "ccc"] 
c = b.insert( 1, "<strong>")
  #=> ["aaa", "<strong>", "bbb", "ccc"]
d = c.insert(-2, "<\/strong>")
  #=> ["aaa", "<strong>", "bbb", "</strong>", "ccc"]
d.join
  #=> "aaa<strong>bbb</strong>ccc"

我们在正则表达式中需要两个捕获组。第一个(具有第一个左括号)捕获我们想要的字符串。第二个字符捕获第一个字符(.)。这是必需的,以便我们可以要求后跟零个或多个该字符的副本\2*

以下是另一种方法:

def stuff_tags(str, tag)    
  str.chars.chunk {|c| c}
    .map {|_,a| a.join}
    .insert( 1, "<#{tag}>")
    .insert(-2, "<\/#{tag}>")
    .join
end

以上ab的计算更改为以下内容:

a = 'aaabbbccc'.chars.chunk {|c| c}
  #=> #<Enumerator: #<Enumerator::Generator:0x000001021622d8>:each>
  # a.to_a => [["a",["a","a","a"]],["b",["b","b","b"]],["c",["c","c","c"]]]
b = a.map {|_,a| a.join }
  #=> ["aaa", "bbb", "ccc"]