只将字符串的第一个字符大写,而不用管其他字符? (Rails)

我试图让 Rails 将字符串的第一个字符大写,而让其他字符保持原样。我遇到了一个问题“我来自纽约”变成了“我来自纽约”

我将使用什么方法来选择第一个字符?

Thanks

编辑: 我试图实现 macek 的建议,但是我得到了一个 “未定义的方法’资本化’”错误。代码在没有大写行的情况下工作得很好。谢谢你的帮助!

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

编辑2: 让它工作。谢谢你的帮助!

编辑3: 等等,不,我没有... 这是我的列表模型。

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

编辑4: 尝试了 macek 的编辑,仍然得到一个 未定义的方法‘大写’”错误。我能做错什么?

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

编辑5: 这太奇怪了。通过使用下面的代码行,我可以消除未定义的方法错误。问题是它似乎用数字代替了第一个字母。例如,它没有将 中的 大写,而是将 变成了121

self.title[0] = title[0].to_s.capitalize
113641 次浏览
string = "i'm from New York"
string.split(/\s+/).each{ |word,i| word.capitalize! unless i > 0 }.join(' ')
# => I'm from New York

编辑2

我似乎无法复制你的“麻烦”。继续并运行这个本地 Ruby 脚本。它会生成您要查找的确切输出,并且 Rails 支持所有这些方法。你在哪些方面有问题?

#!/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

输出

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..."

剪辑

根据您的编辑,您可以尝试这样的东西。

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

这样就行了

s = "i'm from New York"
s[0] = s[0].capitalize
#=> I'm from New York

在尝试对整个字符串使用 String#capitalize时,您看到的是 I'm from new york,因为该方法:

返回 STR的副本,其中第一个字符转换为大写,其余字符转换为小写。

"hello".capitalize    #=> "Hello"
"HELLO".capitalize    #=> "Hello"
"123ABC".capitalize   #=> "123abc"

Titleize 将大写每一个字。 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)

更新:

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..."

这个应该可以:

title = "test test"
title[0] = title[0].capitalize
puts title # "Test test"

更简短的版本可以是:

s = "i'm from New York..."
s[0] = s.capitalize[0]

注意,如果您需要处理多字节字符,也就是说,如果您必须将站点国际化,那么 s[0] = ...解决方案是不够的。这个 Stack Overflow 问题建议使用 unicode-util gem

Ruby 1.9: 如何正确使用大写和小写的多字节字符串?

剪辑

实际上,避免奇怪的字符串编码的一个更简单的方法是使用 字符串 # mb _ chars:

s = s.mb_chars
s[0] = s.first.upcase
s.to_s

没有人提到 gsub,所以你可以简洁地做到这一点。

string.gsub(/^([a-z])/) { $1.capitalize }

例如:

 > 'caps lock must go'.gsub(/^(.)/) { $1.capitalize }
=> "Caps lock must go"

你可以使用人性化。 If you don't need underscores or other capitals in your text lines.

输入:

"i'm from New_York...".humanize

产出:

"I'm from new york..."

一个面向对象的解决方案:

class String
def capitalize_first_char
self.sub(/^(.)/) { $1.capitalize }
end
end

然后你可以这样做:

"i'm from New York".capitalize_first_char

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 }
str = "this is a Test"
str.sub(/^./, &:upcase)
# => "This is a Test"

也许是最简单的方法。

s = "test string"
s[0] = s[0].upcase
# => "Test string"
my_string = "hello, World"
my_string.sub(/\S/, &:upcase) # => "Hello, World"

如果而且只有当 OP 想要对 String 对象进行猴子修补时,才可以使用这种方法

class String
# Only capitalize first letter of a string
def capitalize_first
self.sub(/\S/, &:upcase)
end
end

现在使用它:

"i live in New York".capitalize_first #=> I live in New York
str.sub(/./, &:capitalize)

Rails5.0.0. beta 4开始,你可以使用新的 String#upcase_first方法或者 ActiveSupport::Inflector#upcase_first来完成它。

那么

"i'm from New York...".upcase_first

将输出:

"I'm from New York..."

从版本5.2.3开始的 Rails 具有 Upcase _ first方法。

例如,"my Test string".upcase_first将返回 My Test string

"i'm from New York".camelize
=> "I'm from New York"