Capitalize only first character of string and leave others alone? (Rails)
I'm trying to get Rails to capitalize the first character of a string, and leave all the others the way they are. I'm running into a problem where "i'm from New York" gets turned into "I'm from new york."
What method would I use to select the first character?
Thanks
EDIT: I tried to implement what macek suggested, but I'm getting a "undefined method `capitalize'" error. The code works fine without the capitalize line. Thanks for the help!
def fixlistname!
self.title = self.title.lstrip + (title.ends_with?("...") ? "" : "...")
self.title[0] = self.title[0].capitalize
errors.add_to_base("Title must start with \"You know you...\"") unless self.title.starts_with? 'You know you'
end
开发者_如何学运维EDIT 2: Got it working. Thanks for the help!
EDIT 3: Wait, no I didn't... Here's what I have in my list model.
def fixlistname!
self.title = self.title.lstrip + (title.ends_with?("...") ? "" : "...")
self.title.slice(0,1).capitalize + self.title.slice(1..-1)
errors.add_to_base("Title must start with \"You know you...\"") unless self.title.starts_with? 'You know you'
end
EDIT 4: Tried macek's edit, and still getting an undefined method `capitalize'" error. What could I be doing wrong?
def fixlistname!
self.title = title.lstrip
self.title += '...' unless title.ends_with?('...')
self.title[0] = title[0].capitalize
errors.add_to_base('Title must start with "You know you..."') unless title.starts_with?("You know you")
end
EDIT 5: This is weird. I'm able to get rid of the undefined method error by using the line below. The problem is that it seems to replace the first letter with a number. For example, instead of capitalizing the y in You, it turns the y into a 121
self.title[0] = title[0].to_s.capitalize
This should do it:
title = "test test"
title[0] = title[0].capitalize
puts title # "Test test"
Titleize will capitalise every word. This line feels hefty, but will guarantee that the only letter changed is the first one.
new_string = string.slice(0,1).capitalize + string.slice(1..-1)
Update:
irb(main):001:0> string = "i'm from New York..."
=> "i'm from New York..."
irb(main):002:0> new_string = string.slice(0,1).capitalize + string.slice(1..-1)
=> "I'm from New York..."
You can use humanize. If you don't need underscores or other capitals in your text lines.
Input:
"i'm from New_York...".humanize
Output:
"I'm from new york..."
As of Rails 5.0.0.beta4 you can use the new String#upcase_first
method or ActiveSupport::Inflector#upcase_first
to do it. Check this blog post for more info.
So
"i'm from New York...".upcase_first
Will output:
"I'm from New York..."
str = "this is a Test"
str.sub(/^./, &:upcase)
# => "This is a Test"
An object oriented solution:
class String
def capitalize_first_char
self.sub(/^(.)/) { $1.capitalize }
end
end
Then you can just do this:
"i'm from New York".capitalize_first_char
str.sub(/./, &:capitalize)
Edit 2
I can't seem to replicate your trouble. Go ahead and run this native Ruby script. It generates the exact output your looking for, and Rails supports all of these methods. What sort of inputs are you having trouble with?
#!/usr/bin/ruby
def fixlistname(title)
title = title.lstrip
title += '...' unless title =~ /\.{3}$/
title[0] = title[0].capitalize
raise 'Title must start with "You know you..."' unless title =~ /^You know you/
title
end
DATA.each do |title|
puts fixlistname(title)
end
__END__
you know you something WITH dots ...
you know you something WITHOUT the dots
you know you something with LEADING whitespace...
you know you something with whitespace BUT NO DOTS
this generates error because it doesn't start with you know you
output
You know you something WITH dots ...
You know you something WITHOUT the dots...
You know you something with LEADING whitespace...
You know you something with whitespace BUT NO DOTS...
RuntimeError: Title must start with "You know you..."
Edit
Based on your edit, you can try something like this.
def fixlistname!
self.title = title.lstrip
self.title += '...' unless title.ends_with?('...')
self.title[0] = title[0].capitalize
errors.add_to_base('Title must start with "You know you..."') unless title.starts_with?("You know you")
end
Original
This will do the trick
s = "i'm from New York"
s[0] = s[0].capitalize
#=> I'm from New York
When trying to use String#capitalize
on the whole string, you were seeing I'm from new york
because the method:
Returns a copy of str with the first character converted to uppercase and the remainder to lowercase.
"hello".capitalize #=> "Hello"
"HELLO".capitalize #=> "Hello"
"123ABC".capitalize #=> "123abc"
my_string = "hello, World"
my_string.sub(/\S/, &:upcase) # => "Hello, World"
No-one's mentioned gsub, which lets you do this concisely.
string.gsub(/^([a-z])/) { $1.capitalize }
Example:
> 'caps lock must go'.gsub(/^(.)/) { $1.capitalize }
=> "Caps lock must go"
Most of these answers edit the string in place, when you are just formatting for view output you may not want to be changing the underlying string so you can use tap
after a dup
to get an edited copy
'test'.dup.tap { |string| string[0] = string[0].upcase }
If and only if OP would want to do monkey patching on String object, then this can be used
class String
# Only capitalize first letter of a string
def capitalize_first
self.sub(/\S/, &:upcase)
end
end
Now use it:
"i live in New York".capitalize_first #=> I live in New York
An even shorter version could be:
s = "i'm from New York..."
s[0] = s.capitalize[0]
Note that if you need to deal with multi-byte characters, i.e. if you have to internationalize your site, the s[0] = ...
solution won't be adequate. This Stack Overflow question suggests using the unicode-util gem
Ruby 1.9: how can I properly upcase & downcase multibyte strings?
EDIT
Actually an easier way to at least avoid strange string encodings is to just use String#mb_chars:
s = s.mb_chars
s[0] = s.first.upcase
s.to_s
Rails starting from version 5.2.3 has upcase_first method.
For example, "my Test string".upcase_first
will return My Test string
.
Perhaps the easiest way.
s = "test string"
s[0] = s[0].upcase
# => "Test string"
"i'm from New York".camelize
=> "I'm from New York"
string = "i'm from New York"
string.split(/\s+/).each{ |word,i| word.capitalize! unless i > 0 }.join(' ')
# => I'm from New York
精彩评论