tags:

views:

425

answers:

5

Hi, all.

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!

+3  A: 
"HELLO WORLD HOW ARE YOU".gsub(/\w+/) do |word|
  word.capitalize
end
#=> "Hello World How Are You"
sepp2k
Excellent and terse. Explanation: gsub replaces all occurrences. The regex means 'any substring consisting of a word character (`\w'), followed by 0 or more word characters (`+`)." Note that this can be a one-liner if you use {|word| word.capitalize} instead of `do` and `end` - it's just a matter of preference.
Nathan Long
You could also easily add a conditional statement to only capitalize certain words - `if wordArray.include?(word) word.capitalize else word` (add line breaks to run)
Nathan Long
+2  A: 
 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 (" ").

bantic
Note that this will turn multiple consecutive spaces into one and break if the string contains newlines or tabs.
sepp2k
+3  A: 

From ActiveSupport

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

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

Simone Carletti
+2  A: 

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

"MY STRING HERE".titlize
# => "My String Here"
James A. Rosen
+2  A: 

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.

Jörg W Mittag