86
str = "Hello☺ World☹"

预期输出为:

"Hello:) World:("

我可以做这个:str.gsub("☺", ":)").gsub("☹", ":(")

有没有其他方法可以让我在一个函数调用中做到这一点?就像是:

str.gsub(['s1', 's2'], ['r1', 'r2'])
4

7 回答 7

127

从 Ruby 1.9.2 开始,String#gsub接受 hash 作为第二个参数来替换匹配的键。您可以使用正则表达式来匹配需要替换的子字符串,并为要替换的值传递哈希值。

像这样:

'hello'.gsub(/[eo]/, 'e' => 3, 'o' => '*')    #=> "h3ll*"
'(0) 123-123.123'.gsub(/[()-,. ]/, '')    #=> "0123123123"

在 Ruby 1.8.7 中,您可以使用块实现相同的效果:

dict = { 'e' => 3, 'o' => '*' }
'hello'.gsub /[eo]/ do |match|
   dict[match.to_s]
 end #=> "h3ll*"
于 2011-11-15T07:03:57.593 回答
42

设置映射表:

map = {'☺' => ':)', '☹' => ':(' }

然后构建一个正则表达式:

re = Regexp.new(map.keys.map { |x| Regexp.escape(x) }.join('|'))

最后,gsub

s = str.gsub(re, map)

如果您被困在 1.8 土地上,那么:

s = str.gsub(re) { |m| map[m] }

如果Regexp.escape您要替换的任何内容在正则表达式中具有特殊含义,则需要在其中。或者,感谢 steenslag,您可以使用:

re = Regexp.union(map.keys)

报价将为您处理。

于 2011-11-15T07:14:09.843 回答
38

你可以这样做:

replacements = [ ["☺", ":)"], ["☹", ":("] ]
replacements.each {|replacement| str.gsub!(replacement[0], replacement[1])}

可能有更有效的解决方案,但这至少使代码更干净

于 2011-11-15T06:56:25.557 回答
20

派对迟到了,但如果你想用一个替换某些字符,你可以使用正则表达式

string_to_replace.gsub(/_|,| /, '-')

在此示例中,gsub 将下划线 (_)、逗号 (,) 或 () 替换为破折号 (-)

于 2013-03-26T14:02:41.600 回答
8

另一种简单但易于阅读的方法如下:

str = '12 ene 2013'
map = {'ene' => 'jan', 'abr'=>'apr', 'dic'=>'dec'}
map.each {|k,v| str.sub!(k,v)}
puts str # '12 jan 2013'
于 2013-02-25T06:21:39.900 回答
6

您还可以使用 tr 一次替换字符串中的多个字符,

例如,将“h”替换为“m”,将“l”替换为“t”

"hello".tr("hl", "mt")
 => "metto"

看起来比 gsub 简单、整洁、更快(虽然差别不大)

puts Benchmark.measure {"hello".tr("hl", "mt") }
  0.000000   0.000000   0.000000 (  0.000007)

puts Benchmark.measure{"hello".gsub(/[hl]/, 'h' => 'm', 'l' => 't') }
  0.000000   0.000000   0.000000 (  0.000021)
于 2017-05-24T17:06:02.353 回答
1

上面提到naren的答案时,我会选择

tr = {'a' => '1', 'b' => '2', 'z' => '26'}
mystring.gsub(/[#{tr.keys}]/, tr)

所以 'zebraazzeebra'.gsub(/[#{tr.keys}]/, tr)返回 “26e2r112626ee2r1”

于 2019-02-13T13:33:17.110 回答