更换,直到所有出现的情况都被移除

时间:2017-03-16 11:55:04

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4

我有以下字符串:

",||||||||||||||"
",|||||a|||||,|"

我希望所有出现的",|"都替换为",,"

输出应如下:

",,,,,,,,,,,,,,,"
",,,,,,a|||||,,"

当我在字符串上运行.gsub(',|', ',,')时,我得不到所需的输出。

",,|||||||||||||"
",,||||a|||||,,"

那是因为它没有多次运行gsub。 是否有类似的递归运行方法。

4 个答案:

答案 0 :(得分:8)

正则表达式匹配不能重叠。因为匹配是用于替换的,所以你不能这样做。这是两个解决方法:

str = ",|||||a|||||,|"
while str.gsub!(/,\|/, ',,'); end

str = ",|||||a|||||,|"
str.gsub!(/,(\|+)/) { "," * ($1.length + 1) }

答案 1 :(得分:5)

smoke_weed_every_day = lambda do |piper|
  commatosed = piper.gsub(',|', ',,')
  commatosed == piper ? piper : smoke_weed_every_day.(commatosed)
end

smoke_weed_every_day.(",||||||||||||||") # => ",,,,,,,,,,,,,,,"
smoke_weed_every_day.(",|||||a|||||,|")  # => ",,,,,,a|||||,,"

答案 2 :(得分:2)

来自我的旧图书馆。此方法迭代,直到块输出等于其输入:

def loop_until_convergence(x)
  x = yield(previous = x) until previous == x
  x
end

puts loop_until_convergence(',||||||||||||||') { |s| s.gsub(',|', ',,') }
# ",,,,,,,,,,,,,,,"
puts loop_until_convergence(',|||||a|||||,|') { |s| s.gsub(',|', ',,') }
# ",,,,,,a|||||,,"

作为奖励,您可以在very few iterations中计算平方根:

def root(n)
  loop_until_convergence(1) { |x| 0.5 * (x + n / x) }
end

p root(2)
# 1.414213562373095
p root(3)
# 1.7320508075688772

答案 3 :(得分:0)

与@ Amandan的第二个解决方案一样,没有必要进行迭代,直到不再进行进一步的更改。

COMMA = ','
PIPE  = '|'

def replace_pipes_after_comma(str)
  run = false
  str.gsub(/./) do |s|
    case s
    when PIPE
      run ? COMMA : PIPE    
    when COMMA
      run = true
      COMMA
    else
      run = false
      s
    end
  end
end

replace_pipes_after_comma ",||||||||||||||"
  #=>                     ",,,,,,,,,,,,,,," 
replace_pipes_after_comma ",|||||a|||||,|"
  #=>                     ",,,,,,a|||||,,"