2

I think I'm close, but the regex isn't evaluating. Hoping someone may know why.

def new_title(title)
  words = title.split(' ')
  words = [words[0].capitalize] + words[1..-1].map do |w|
    if w =~ /and|an|a|the|in|if|of/
      w
    else
      w.capitalize
    end
  end
  words.join(' ')
end

When I pass in lowercase titles, they get returned as lowercase.

3 Answers 3

3

You need to properly anchor your regular expression:

new_title("the last hope")
# => "The last Hope"

This is because /a/ matches a word with an a in it. /\Aa\Z/ matches a string that consists entirely of a, and /\A(a|of|...)\Z/ matches against a set of words.

In any case, what you might want is this:

case (w)
when 'and', 'an', 'a', 'the', 'in', 'if', 'of'
  w
else
  w.capitalize
end

Using a regular expression here is a bit heavy handed. What you want is an exclusion list.

Sign up to request clarification or add additional context in comments.

Comments

1

This is called titleize, and is implemented like this:

def titleize(word)
  humanize(underscore(word)).gsub(/\b('?[a-z])/) { $1.capitalize }
end

Se the doc.

If you want fancy titlezing, check out granth's titleize

Comments

0

Your regular expression should be checking the whole word (^word$). Anyway, isn't more simple to use Enumerable#include?:

def new_title(title)
  words = title.split(' ')
  rest_words = words.drop(1).map do |word|
    %w(and an a the in if of).include?(word) ? word : word.capitalize
  end
  ([words[0].capitalize] + rest_words).join(" ")
end

1 Comment

Yeah, include is definitely what I'd normally do, but I was doing a bit of practice with regular expressions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.