user5493835
user5493835

Reputation:

gsub method and regex (case sensitive and case insensitive)

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

Answers (4)

Cary Swoveland
Cary Swoveland

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

Casimir et Hippolyte
Casimir et Hippolyte

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

charlysisto
charlysisto

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

Santhosh
Santhosh

Reputation: 29124

You can use a Hash. eg:

h = {'a' => '@', 'b' => 'B', 'A' => 'E'}
"aAbBcC".gsub(/[abA]/, h)
# => "@EBBcC" 

Upvotes: 2

Related Questions