Reputation: 2175
Ok. It's late and I'm tired.
I want to match a character in a string. Specifically, the appearance of 'a'. As in "one and a half".
If I have a string which is all lowercase.
"one and a half is always good" # what a dumb example. No idea how I thought of that.
and I call titleize on it
"one and a half is always good".titleize #=> "One And A Half Is Always Good"
This is wrong because the 'And' and the 'A' should be lowercase. Obviously.
So, I can do
"One and a Half Is always Good".titleize.tr('And', 'and') #=> "One and a Half Is always Good"
My question: how do I make the "A" an "a" and without making the "Always" into "always"?
Upvotes: 0
Views: 209
Reputation: 16779
I like Greg's two-liner (first titleize, then use a regex to downcase selected words.) FWIW, here's a function I use in my projects. Well tested, although much more verbose. You'll note that I'm overriding titleize in ActiveSupport:
class String
#
# A better titleize that creates a usable
# title according to English grammar rules.
#
def titleize
count = 0
result = []
for w in self.downcase.split
count += 1
if count == 1
# Always capitalize the first word.
result << w.capitalize
else
unless ['a','an','and','by','for','in','is','of','not','on','or','over','the','to','under'].include? w
result << w.capitalize
else
result << w
end
end
end
return result.join(' ')
end
end
Upvotes: 2
Reputation: 160551
This does it:
require 'active_support/all'
str = "one and a half is always good" #=> "one and a half is always good"
str.titleize.gsub(%r{\b(A|And|Is)\b}i){ |w| w.downcase } #=> "One and a Half is Always Good"
or
str.titleize.gsub(%r{\b(A(nd)?|Is)\b}i){ |w| w.downcase } #=> "One and a Half is Always Good"
Take your pick of either of the last two lines. The regex pattern could be created elsewhere and passed in as a variable, for maintenance or code cleanliness.
Upvotes: 2