str = "Hello☺ World☹"
Expected output is:
"Hello:) World:("
I can do this: str.gsub("☺", ":)").gsub("☹", ":(")
str.gsub("☺", ":)").gsub("☹", ":(")
Is there any other way so that I can do this in a single function call?. Something like:
str.gsub(['s1', 's2'], ['r1', 'r2'])
You could do something like this:
replacements = [ ["☺", ":)"], ["☹", ":("] ] replacements.each {|replacement| str.gsub!(replacement[0], replacement[1])}
There may be a more efficient solution, but this at least makes the code a bit cleaner
Since Ruby 1.9.2, String#gsub accepts hash as a second parameter for replacement with matched keys. You can use a regular expression to match the substring that needs to be replaced and pass hash for values to be replaced.
String#gsub
Like this:
'hello'.gsub(/[eo]/, 'e' => 3, 'o' => '*') #=> "h3ll*" '(0) 123-123.123'.gsub(/[()-,. ]/, '') #=> "0123123123"
In Ruby 1.8.7, you would achieve the same with a block:
dict = { 'e' => 3, 'o' => '*' } 'hello'.gsub /[eo]/ do |match| dict[match.to_s] end #=> "h3ll*"
Set up a mapping table:
map = {'☺' => ':)', '☹' => ':(' }
Then build a regex:
re = Regexp.new(map.keys.map { |x| Regexp.escape(x) }.join('|'))
And finally, gsub:
gsub
s = str.gsub(re, map)
If you're stuck in 1.8 land, then:
s = str.gsub(re) { |m| map[m] }
You need the Regexp.escape in there in case anything you want to replace has a special meaning within a regex. Or, thanks to steenslag, you could use:
Regexp.escape
re = Regexp.union(map.keys)
and the quoting will be take care of for you.
Another simple way, and yet easy to read is the following:
str = '12 ene 2013' map = {'ene' => 'jan', 'abr'=>'apr', 'dic'=>'dec'} map.each {|k,v| str.sub!(k,v)} puts str # '12 jan 2013'
Late to the party but if you wanted to replace certain chars with one, you could use a regex
string_to_replace.gsub(/_|,| /, '-')
In this example, gsub is replacing underscores(_), commas (,) or ( ) with a dash (-)
You can also use tr to replace multiple characters in a string at once,
Eg., replace "h" to "m" and "l" to "t"
"hello".tr("hl", "mt") => "metto"
looks simple, neat and faster (not much difference though) than 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)
Riffing on naren's answer above, I'd go with
tr = {'a' => '1', 'b' => '2', 'z' => '26'} mystring.gsub(/[#{tr.keys}]/, tr)
So 'zebraazzeebra'.gsub(/[#{tr.keys}]/, tr) returns "26e2r112626ee2r1"
'zebraazzeebra'.gsub(/[#{tr.keys}]/, tr)