Reputation:
In ruby, I want to substitute some letters in a string, is there a better way of doing this?
string = "my random string"
string.gsub(/a/, "@").gsub(/i/, "1").gsub(/o/, "0")`
And if I want to substitute both "a" and "A" with a "@", I know I can do .gsub(/a/i, "@")
, but what if I want to substitute every "a" with an "e" and every "A" with an "E"? Is there a way of abstracting it instead of specifying both like .gsub(/a/, "e").gsub(/A/, "E")
?
Upvotes: 1
Views: 1270
Reputation: 110685
Here are two variants of @Santosh's answer:
str ="aAbBcC"
h = {'a' => '@', 'b' => 'B', 'A' => 'E'}
#1
str.gsub(/[#{h.keys.join}]/, h) #=> "@EBBcC"
#2
h.default_proc = ->(_,k) { k }
str.gsub(/./, h) #=> "@EBBcC"
These offer better maintainability should h
could change in future
Upvotes: 1
Reputation: 89557
Not really an answer to your question, but more an other way to proceed: use the translation:
'aaAA'.tr('aA', 'eE')
# => 'eeEE'
For the same transformation, you can also use the ascii table:
'aaAA'.gsub(/a/i) {|c| (c.ord + 4).chr}
# => 'eeEE'
other example (the last character is used by default):
'aAaabbXXX'.tr('baA', 'B@')
# => '@@@@BBXXX'
Upvotes: 2
Reputation: 3700
You can also pass gsub a block
"my random string".gsub(/[aoi]/) do |match|
case match; when "a"; "@"; when "o"; "0"; when "i"; "I" end
end
# => "my r@nd0m strIng"
The use of a hash is of course much more elegant in this case, but if you have complex rules of substitution it can come in handy to dedicate a class to it.
"my random string".gsub(/[aoi]/) {|match| Substitute.new(match).result}
# => "my raws0m strAINng"
Upvotes: 0
Reputation: 29124
You can use a Hash. eg:
h = {'a' => '@', 'b' => 'B', 'A' => 'E'}
"aAbBcC".gsub(/[abA]/, h)
# => "@EBBcC"
Upvotes: 2