仅将字符串的第一个字符大写并留下其他字符?

Capitalize only first character of string and leave others alone? (Rails)

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

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

谢谢

编辑:我试图实现Macek的建议,但我得到了一个"未定义的方法‘大写’"错误。没有大写行,代码就可以正常工作。谢谢你的帮助!

1
2
3
4
5
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:等等,不,我没有……以下是我的列表模型。

1
2
3
4
5
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的编辑,但仍然得到一个未定义的方法"大写"错误。我可能做错什么了?

1
2
3
4
5
6
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:这很奇怪。我可以使用下面的行来消除未定义的方法错误。问题是,它似乎用数字替换了第一个字母。例如,它不是将您的y大写,而是将y变为121

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


应该这样做:

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


标题将把每一个字都大写。这一行感觉很重,但可以保证唯一更改的字母是第一个。

1
new_string = string.slice(0,1).capitalize + string.slice(1..-1)

更新:

1
2
3
4
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..."


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

输入:

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

输出:

1
"I'm from new york..."


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


从Rails 5.0.0.beta4开始,您可以使用新的String#upcase_first方法或ActiveSupport::Inflector#upcase_first方法来完成此操作。有关详细信息,请查看此日志。


面向对象的解决方案:

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

然后你可以这样做:

1
"i'm from New York".capitalize_first_char


1
str.sub(/./, &:capitalize)

1
2
my_string ="hello, World"
my_string.sub(/\S/, &:upcase) # =>"Hello, World"


编辑2

我好像不能复制你的麻烦。继续运行这个本机Ruby脚本。它生成您要查找的确切输出,Rails支持所有这些方法。您遇到了什么类型的输入问题?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/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

输出

1
2
3
4
5
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..."

编辑

根据您的编辑,您可以尝试类似的操作。

1
2
3
4
5
6
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

原件

这就行了

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

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

Returns a copy of str with the first character converted to uppercase and the remainder to lowercase.

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


这些答案中的大多数都是就地编辑字符串,当您只是格式化视图输出时,您可能不想更改基础字符串,这样您就可以在dup之后使用tap获得编辑过的副本。

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

如果且仅当op希望对字符串对象进行monkey修补时,则可以使用

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

现在使用它:

1
"i live in New York".capitalize_first #=> I live in New York


没有人提到过GSUB,它让您能够简洁地完成这项工作。

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

例子:

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

也许是最简单的方法。

1
2
3
s ="test string"
s[0] = s[0].upcase
# =>"Test string"

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

Ruby1.9:我如何正确地升级大小写多字节字符串?

编辑

实际上,至少要避免奇怪的字符串编码,一个更简单的方法是只使用字符串mb覕字符:

1
2
3
s = s.mb_chars
s[0] = s.first.upcase
s.to_s

更简短的版本可能是:

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

字符串上的分类方法怎么样?

1
'somESTRIng'.classify

输出:

1
#rails => 'SomESTRIng'


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