Reputation: 110960
With Ruby, is it possible to replace a string and conserve capitalisation.
Idea is to match "good day" and turn it into "holler" and preserve the original capitalisation. Example:
Before:
Good day to you sir and lady.
Hello and good day.
After:
Holler to you sir and lady.
Hello and holler.
Upvotes: 2
Views: 242
Reputation: 5740
If you are planning to keep part of the string and append to it, use back reference and case-insensitive search pattern
yourstring.gsub(/(good day)/i, "\\1 and good night")
You can find explanation on how regular expressions work in ruby
in rubular
Update
Since, as you state in your comment and your updated question, you want the first letter of the replacement capitalized or not, according to pattern, I think this slightly verbose yet efficient gsub
approach can help you:
string = "Good day to you sir and lady. \nHello and good day."
puts string.gsub(/[gG]ood day/, 'good day' =>'holler', 'Good day'=>'Holler')
# Holler to you sir and lady.
# Hello and holler.
As per ruby 1.8.7
, gsub
can accept a hash as a second parameter with alternative replacements of the possible matches the pattern describes. Thus, the above syntax is equivalent to:
puts string.gsub(/[gG]ood day/, {'good day' =>'holler', 'Good day'=>'Holler'})
Upvotes: 1
Reputation: 54233
This method :
old_str
in text
old_str
found :
new_str
and old_str
characters in parallelold_str
case on new_str
def case_aware_replace(text, old_str, new_str)
text.gsub(/#{old_str}/i) do |word|
new_str.chars.zip(word.chars).map do |new_char, old_char|
if old_char
old_char.downcase == old_char ? new_char : new_char.upcase
else
new_char
end
end.join
end
end
puts case_aware_replace('Good day to you sir and lady.', 'good day', 'holler')
#=> Holler to you sir and lady.
puts case_aware_replace('Hello and good day.', 'good day', 'holler')
#=> Hello and holler.
puts case_aware_replace('HELLO GRANDMA!', 'hello', 'hi')
#=> HI GRANDMA!
puts case_aware_replace('AaAaAaA', 'a', 'b')
#=> BbBbBbB
puts case_aware_replace('AaAaAaA', 'a', 'b ')
#=> B b B b B b B
puts case_aware_replace(case_aware_replace(case_aware_replace('IBM', 'i', 'international '),'b', 'business '),'m', 'machines ')
#=> International Business Machines
Upvotes: 1
Reputation: 1703
a = 'Good day to you sir and lady.
Hello and good day.'
a.gsub!('Good day', 'Hellor').gsub!('good day', 'hellor')
would return
Hellor to you sir and lady.
Hello and hellor.
There are only two cases (assuming only initials can be capitalised), replacing two cases directly should be sufficient.
Upvotes: -1
Reputation: 1428
you can use the Regexp escape method with the ignore case option to do such a thing:
reg = Regexp.new(Regexp.escape("good day"), Regexp::IGNORECASE)
"good day".gsub(reg){|match| "#{match} and good night" }
=> "good day and good night"
"Good dAy".gsub(reg){|match| "#{match} and good night" }
=> "Good dAy and good night"
EDIT to match the updated question
using a similar idea to the answer for the original question
"Good day".gsub(reg){|match| "#{match.capitalize == match ? 'Holler' : 'holler'} and good night" }
=> "Holler and good night"
"good day".gsub(reg){|match| "#{match.capitalize == match ? 'Holler' : 'holler'} and good night" }
=> "holler and good night"
Upvotes: 1
Reputation: 23671
You can pass a block to gsub
and you can manipulate the matched string
And the option i
passed will make the regex case insensitive
string = "Good day to you sir and lady."
string.gsub(/good day/i) { |m| "#{m} and good night" }
#=> "Good day and good night to you sir and lady."
string = "Hello and good day."
string.gsub(/good day/i) { |m| "#{m} and good night" }
#=> "Hello and good day and good night."
Refer gsub
Upvotes: 1
Reputation: 6564
sure there will be more elegant solutions, but this can also help.
2.3.1 :003 > a = "Good day to you sir and lady".downcase.gsub('good day', 'good day and good night').capitalize
=> "Good day and good night to you sir and lady"
what i've done is,
Upvotes: -1