我有以下字符串:
",||||||||||||||"
",|||||a|||||,|"
我希望所有出现的",|"
都替换为",,"
输出应如下:
",,,,,,,,,,,,,,,"
",,,,,,a|||||,,"
当我在字符串上运行.gsub(',|', ',,')
时,我得不到所需的输出。
",,|||||||||||||"
",,||||a|||||,,"
那是因为它没有多次运行gsub
。
是否有类似的递归运行方法。
答案 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|||||,,"