仅将字符串的第一个字符大写,而让其他人静静吗?(路轨)


102

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

我将使用哪种方法选择第一个字符?

谢谢

编辑:我试图实现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的编辑,但仍然收到未定义的方法'capitalize'“错误。我怎么做错了?

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

基于EDIT 3,您需要从开始第2行self.title = 。同样,在所有3行中,您只需要self.title=(等号)的左侧。在其他地方,您可以使用title。有关示例,请参见我的答案中的编辑内容。
maček

2
Edit4中的问题是您只有一个字符-不再是字符串-因此它无法识别字符串函数“ capitalize”。
Taryn East 2010年

编辑5的问题是title [0]是一个fixnum,因此调用title [0] .to_s只会给您字符编号(即121作为字符串:“ 121”)。如果需要,可以执行self.title [0] = title.first.capitalize!
尼克(Nick)

我添加了#upcase_first_case并发出了请求请求:github.com/rails/rails/pull/15319。随时在此处添加您的反馈。
2014年

Answers:


93

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

等待,仍然无法正常工作。错误警报:/我想我只是在错误地实现它。
Daniel O'Connor 2010年

1
丹尼尔-“接受”已解决您问题的答案通常是一种很好的形式。您可以通过单击答案左侧的“刻度”来完成此操作。:)
Taryn East

1
我误解了这个问题,否则我想给你1分。我一直在寻找.titleize而不是.capitalize。无论如何,谢谢Taryn!
Eric Wanchic 2014年

OOC-为什么这会阻止您投票?我是否正确回答了原始海报的问题?如果您是这样-那就投票。它不必依赖于其他任何东西... :)
Taryn East 2014年

2
因此,结果如下: s[0].capitalize + s[1..-1] if s.present?
Alex Escalante

126

应该这样做:

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

40
或更简而言之,title[0] = title[0].capitalize
乔恩·加文

这是一个非常优雅的解决方案。
卡鲁

1
@JonGarvin title [0] .capitalize不起作用(至少在Ruby 1.8.7中有效),因为title [0]返回一个Fixnum,并且大写期望字符串。走。
尼克

2
不能羞耻title.first.capitalize!
亚当·怀特

1
capitalize将第一个字母之后的所有字母都转换为小写,因此不适用于问题中显示的字符串(“我来自纽约”)。
马克·施耐德

57

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

输入:

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

输出:

"I'm from new york..."

7
该OP特别想避免“纽约”
phatmann

嗯,确实,我的回答有点太快了。
Bartuzz 2013年

17
@Bartuzz即使这不是OP想要的,这也正是我想要的。谢谢!
Yetti 2014年

但是,纽约作为其专有名词是不合语法的,应使用大写字母。
谢恩

请注意,humanizeRails正是ActiveSupport方法。普通红宝石无法做到这一点。
企鹅

51
str = "this is a Test"
str.sub(/^./, &:upcase)
# => "This is a Test"

1
简洁优雅。我相信这应该是最佳答案。
克里斯(Chris)

我同意。我认为这应该是公认的答案。
加里·佩特

一个怪癖是由于^意味着行的开头,"\nfoo"变成"\nFoo"。对于大多数用例来说,这可能很好。由于它是a sub而不是a gsub,即使使用多行字符串,它仍然只会大写一个字母。
Henrik N

可以使用来获得上述限制str.sub(/\S/, &:upcase),它将找到第一个非空白字符并将其大写。
安东尼·潘诺佐

39

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


这真是个好消息!我在想我们现在可以做什么,也许Rails 4的polyfill会很好。
hakunin

请注意,即使使用mb_chars,upcase_first也不处理口音/特殊字符
user3033467

14

面向对象的解决方案:

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

然后,您可以执行以下操作:

"i'm from New York".capitalize_first_char

至少有人用扩展String类来编写优雅的解决方案。
Dmitriy 2013年

@Dmitriy为什么猴子修补字符串类很优雅?
杰拉德·辛普森


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"

+1的原因是直到我在自己的PC上尝试过,我才认为这不会起作用:)
Jeriko 2010年

嗨,谢谢您的帮助。但是我在做什么错呢?我已经编辑了原始问题以包含我的代码。
Daniel O'Connor 2010年

我使用了Taryn的建议并使它生效。谢谢您的帮助!
Daniel O'Connor 2010年

嗨,stackoverflow说您进行了编辑,但是我没看到什么不同吗?
Daniel O'Connor 2010年


4

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

'test'.dup.tap { |string| string[0] = string[0].upcase }

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

2

甚至更短的版本可能是:

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

2

没有人提到的gsub,它使您可以简洁地执行此操作。

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

例:

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



0

字符串的分类方法呢?

'somESTRIng'.classify

输出:

#rails => 'SomESTRIng'

1
它还会做很多其他事情,例如将单词单数化。"hello worlds".classify # => "Hello world"
Pavel Pravosud 2014年

-3
string = "i'm from New York"
string.split(/\s+/).each{ |word,i| word.capitalize! unless i > 0 }.join(' ')
# => I'm from New York

似乎是这样。我是红宝石的新手,而其他答案实际上并没有执行OP所要求的,所以我使它起作用了:D如果我错了,请纠正我,但是AFAIK通过更改string [i]来修改字符串用多种语言工作?
杰里科

3
这是一个特定于Ruby的问题。如果string[i]不能使用其他语言也没关系。请帮助保持StackOverflow整洁,避免这类骇人听闻的答案。我们不能说RTFM,但即使是一个快速的浏览String文档就已经帮助避免这样的答案...
maček
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.