没有gsub替换字符串的优雅方法是什么?

时间:2014-01-14 19:39:09

标签: ruby string replace gsub

我有一些动态字符串,其字符为XX可以通过字符串连续显示或分散。我想将X替换为#

例如,abXXcX12XX。我想要ab#c#12#。这意味着多个连续的X必须仅由一个#替换,如果只有一个X,则也可以由一个#替换。

我试过了:

s = "aXX123Xc56XXX"
s.squeeze('X').gsub('X','#') # => "a#123#c56#"

任何优雅的方式或直接的方法来做同样的操作?

4 个答案:

答案 0 :(得分:12)

我将使用String#tr_s进行如下操作:

  

按照String#tr中的说明处理str的副本,然后删除受翻译影响的区域中的重复字符。

s = "aXX123Xc56XXX"
s.tr_s('X','#') # => "a#123#c56#"

答案 1 :(得分:4)

不确定为什么你不会在这里使用gsub? 正则表达式看起来效果很好:

"aXX123Xc56XXX".gsub(/X+/, "#")
=> "a#123#c56#"  

这样做的原因是/X+/会匹配X字符的一个或多个,因此一行中多个X只会产生一个匹配并被一个#替换。

答案 2 :(得分:1)

 pry(main)> "aXX123Xc56XXX".gsub(/X+/, "#")
=> "a#123#c56#"

答案 3 :(得分:1)

虽然gsubtr_s都可以完成任务,但这是使用tr_s的令人信服的理由:

require 'fruity'

STRING = 'aXX123Xc56XXX' * 1000

compare do
  using_tr_s { STRING.tr_s('X', '#') }
  using_gsub { STRING.gsub(/X+/, '#') }
end

在我的笔记本电脑上运行之后会导致:

Running each test 16 times. Test will take about 1 second.
using_tr_s is faster than using_gsub by 5x ± 0.1

正则表达式引擎已经看到了很多加速,但它仍然会被非锚定查找击败。如果有一种方法可以告诉它从字符串的开头或结尾开始,我们会看到它的速度很快,而且,对于某些搜索/替换操作,我已经看到它超越了其他所有内容。使用的模式至关重要;写得不好的人会使发动机瘫痪,所以要小心你的用途。