107

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

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

谢谢

编辑:我试图实现 macek 的建议,但我得到一个“未定义的方法 `capitalize'”错误。没有大写行,代码可以正常工作。谢谢您的帮助!

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:这很奇怪。通过使用下面的行,我可以摆脱未定义的方法错误。问题是它似乎用数字替换了第一个字母。例如,不是将You中的y大写,而是将y变成 121

self.title[0] = title[0].to_s.capitalize
4

19 回答 19

131

这应该这样做:

title = "test test"     
title[0] = title[0].capitalize
puts title # "Test test"
于 2011-08-22T17:02:08.530 回答
96

Titleize 将大写每个单词。这条线感觉很重,但可以保证唯一改变的字母是第一个。

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..."
于 2010-04-15T16:13:46.573 回答
61

您可以使用人性化。如果您的文本行中不需要下划线或其他大写字母。

输入:

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

输出:

"I'm from new york..."
于 2012-06-28T10:43:28.400 回答
55
str = "this is a Test"
str.sub(/^./, &:upcase)
# => "This is a Test"
于 2013-03-15T19:23:19.363 回答
52

Rails 5.0.0.beta4 开始,您可以使用新String#upcase_first方法或ActiveSupport::Inflector#upcase_first执行此操作。查看此博客文章了解更多信息。

所以

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

将输出:

"I'm from New York..."
于 2016-05-20T01:37:23.370 回答
14

面向对象的解决方案:

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

然后你可以这样做:

"i'm from New York".capitalize_first_char
于 2012-09-14T19:06:15.043 回答
7
str.sub(/./, &:capitalize)
于 2016-02-09T18:50:21.197 回答
6

编辑 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

原来的

这会成功的

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"
于 2010-04-15T15:56:25.387 回答
6
my_string = "hello, World"
my_string.sub(/\S/, &:upcase) # => "Hello, World"
于 2014-05-26T02:06:08.383 回答
4

这些答案中的大多数都在原地编辑字符串,当您只是为视图输出进行格式化时,您可能不想更改基础字符串,因此您可以tap在 a 之后使用dup来获取编辑后的副本

'test'.dup.tap { |string| string[0] = string[0].upcase }
于 2013-01-02T13:26:31.677 回答
3

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

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

例子:

 > 'caps lock must go'.gsub(/^(.)/) { $1.capitalize }
=> "Caps lock must go"
于 2012-06-05T02:42:53.407 回答
3

当且仅当 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
于 2015-11-13T08:07:20.820 回答
2

更短的版本可能是:

s = "i'm from New York..."
s[0] = s.capitalize[0]
于 2011-12-09T07:52:01.137 回答
1

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

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

编辑

实际上,至少避免奇怪的字符串编码的更简单方法是使用String#mb_chars

s = s.mb_chars
s[0] = s.first.upcase
s.to_s
于 2012-05-07T22:17:35.720 回答
1

也许是最简单的方法。

s = "test string"
s[0] = s[0].upcase
# => "Test string"
于 2013-10-09T09:19:26.597 回答
1

从 5.2.3 版本开始的 Rails 具有upcase_first方法。

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

于 2020-10-31T18:52:31.460 回答
0
"i'm from New York".camelize
=> "I'm from New York"
于 2022-02-21T11:44:08.960 回答
-1

string 上的分类方法呢?

'somESTRIng'.classify

输出:

#rails => 'SomESTRIng'
于 2014-05-15T11:40:43.293 回答
-3
string = "i'm from New York"
string.split(/\s+/).each{ |word,i| word.capitalize! unless i > 0 }.join(' ')
# => I'm from New York
于 2010-04-15T15:41:20.600 回答