Converting upper-case string into title-case using Ruby

RubyString

Ruby Problem Overview


I'm trying to convert an all-uppercase string in Ruby into a lower case one, but with each word's first character being upper case. Example:

convert "MY STRING HERE" to "My String Here".

I know I can use the .downcase method, but that would make everything lower case ("my string here"). I'm scanning all lines in a file and doing this change, so is there a regular expression I can use through ruby to achieve this?

Thanks!

Ruby Solutions


Solution 1 - Ruby

If you're using Rails (really all you need is ActiveSupport, which is part of Rails), you can use titleize:

"MY STRING HERE".titleize
# => "My String Here"

If you're using plain Ruby but don't mind loading a small amount of ActiveSupport you can require it first:

require 'active_support/core_ext/string/inflections'
# => true
"MY STRING HERE".titleize
# => "My String Here"

N.B. By default titleize doesn't handle acronyms well and will split camelCaseStrings into separate words. This may or may not be desirable:

"Always use SSL on your iPhone".titleize
# => "Always Use Ssl On Your I Phone"

You can (partially) address this by adding "acronyms":

require 'active_support/core_ext/string/inflections' # If not using Rails
ActiveSupport::Inflector.inflections do |inflect|
  inflect.acronym 'SSL'
  inflect.acronym 'iPhone'
end
"Always use SSL on your iPhone".titleize
# => "Always Use SSL On Your IPhone"

For those who speak the Queen's English (or who struggle to spell titleize), there's no .titleise alias but you can use .titlecase instead.

Solution 2 - Ruby

"HELLO WORLD HOW ARE YOU".gsub(/\w+/) do |word|
  word.capitalize
end
#=> "Hello World How Are You"

Solution 3 - Ruby

While trying to come up with my own method (included below for reference), I realized that there's some pretty nasty corner cases. Better just use the method already provided in Facets, the mostest awesomest Ruby library evar:

require 'facets/string/titlecase'

class String
  def titleize
    split(/(\W)/).map(&:capitalize).join
  end
end

require 'test/unit'
class TestStringTitlecaseAndTitleize < Test::Unit::TestCase
  def setup
    @str = "i just saw \"twilight: new moon\", and man!   it's crap."
    @res = "I Just Saw \"Twilight: New Moon\", And Man!   It's Crap."
  end
  def test_that_facets_string_titlecase_works
    assert_equal @res, @str.titlecase
  end
  def test_that_my_own_broken_string_titleize_works
    assert_equal @res, @str.titleize # FAIL
  end
end

If you want something that more closely complies to typical writing style guidelines (i.e. does not capitalize words like "and"), there are a couple of "titleize" gems on GitHub.

Solution 4 - Ruby

From ActiveSupport

"MY STRING HERE".gsub(/\b('?[a-z])/) { $1.capitalize }

If you are using Rails/ActiveSupport, the method is already available for free.

Solution 5 - Ruby

string = "MY STRING HERE"
string.split(" ").map {|word| word.capitalize}.join(" ")

The way this works: The .split(" ") splits it on spaces, so now we have an array that looks like ["my", "string", "here"]. The map call iterates over each element of the array, assigning it to temporary variable word, which we then call capitalize on. Now we have an array that looks like ["My", "String", "Here"], and finally we turn that array back into a string by joining each element with a space (" ").

Solution 6 - Ruby

"MY STRING HERE".titlecase

Does the job (it's a method in the Rails gem, however) http://apidock.com/rails/String/titlecase

Solution 7 - Ruby

Unicode-aware titlecase for Ruby 2.4.0+:

class String
  def titlecase
    split(/([[:alpha:]]+)/).map(&:capitalize).join
  end
end

>> "я только что посмотрел \"леди исчезает\", и это чума!".titlecase
=> "Я Только Что Посмотрел \"Леди Исчезает\", И Это Чума!"

(based on https://stackoverflow.com/a/1792102/788700)

Solution 8 - Ruby

I've try to improve code... ready for critics and suggestions.

class Book
    attr_accessor :title
    def title=(new_title)
	notcap=%w(and the a in of an)
	str=''
	new_title.gsub(/(\w|\s)\w+/) do |word|
		word.strip!
		if not notcap.include? word
		       word.capitalize! 
		end
	   str += ' ' + word 
	end
	str.strip!
	str = str[0].upcase + str[1..-1]
	@title = str
   end
end

Solution 9 - Ruby

The ruby core itself has no support to convert a string from upper (word) case to capitalized word case.

So you need either to make your own implementation or use an existing gem.

There is a small ruby gem called lucky_case which allows you to convert a string from any of the 10+ supported cases to another case easily:

require 'lucky_case'

# to get capital word case as string
LuckyCase.capital_word_case('MY STRING HERE')    # => 'My String Here'
# or the opposite way
LuckyCase.upper_word_case('Capital Word Case')   # => 'MY STRING HERE'

You can even monkey patch the String class if you want to:

require 'lucky_case/string'

'MY STRING HERE'.capital_word_case  # => 'My String Here'
'MY STRING HERE'.capital_word_case! # => 'My String Here' and overwriting original

Have a look at the offical repository for more examples and documentation:

https://github.com/magynhard/lucky_case

Solution 10 - Ruby

Capitalizes every word in a sentence using ruby, without regex.. because unfortunately those scare me

class Book
	attr_accessor :title
	def title=(new_title)
		result = []
		words = new_title.split(' ')
		words.each do |word|
			capitalized = word[0].upcase + word[1..word.length].downcase
			result.push(capitalized)
		end
		
		@title = result.join(' ')
	end
end

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionwsb3383View Question on Stackoverflow
Solution 1 - RubyJames A. RosenView Answer on Stackoverflow
Solution 2 - Rubysepp2kView Answer on Stackoverflow
Solution 3 - RubyJörg W MittagView Answer on Stackoverflow
Solution 4 - RubySimone CarlettiView Answer on Stackoverflow
Solution 5 - RubybanticView Answer on Stackoverflow
Solution 6 - RubymarcindobryView Answer on Stackoverflow
Solution 7 - RubyAdobeView Answer on Stackoverflow
Solution 8 - RubyK.S.A.View Answer on Stackoverflow
Solution 9 - RubymagynhardView Answer on Stackoverflow
Solution 10 - RubyConnor LeechView Answer on Stackoverflow