Ruby首字母大写每个单词

191

我需要将每个单词的第一个字符变成大写,并将其余字符变为小写...

manufacturer.MFA_BRAND.first.upcase

只能将第一个字母大写,但我需要这样:

ALFA ROMEO => Alfa Romeo
AUDI => Audi
BMW => Bmw
ONETWO THREE FOUR => Onetwo Three Four
8个回答

343
在Rails中:
"kirk douglas".titleize => "Kirk Douglas"
#this also works for 'kirk_douglas'

没有Rails:

"kirk douglas".split(/ |\_/).map(&:capitalize).join(" ")

#OBJECT IT OUT
def titleize(str)
  str.split(/ |\_/).map(&:capitalize).join(" ")
end

#OR MONKEY PATCH IT
class String  
  def titleize
    self.split(/ |\_/).map(&:capitalize).join(" ")
  end
end

不使用Rails(加载Rails的ActiveSupport来修补#titleize方法到String

require 'active_support/core_ext'
"kirk douglas".titleize #=> "Kirk Douglas"

#titleize 处理的一些字符串用例

  • "kirk douglas"
  • "kirk_douglas"
  • "kirk-douglas"
  • "kirkDouglas"
  • "KirkDouglas"

#titleize 的注意事项

Rails 的 titleize 会将横线和下划线转换为空格,并可能产生其他意外结果,尤其是在大小写敏感的情况下,如 @JamesMcMahon 指出的那样:

"hEy lOok".titleize #=> "H Ey Lo Ok"

因为它旨在处理类似驼峰式代码的内容,例如:

"kirkDouglas".titleize #=> "Kirk Douglas"

为了处理这种边缘情况,您可以在运行#titleize之前首先使用#downcase清理字符串。当然,如果您这样做,将会清除任何驼峰式单词的分隔符:
"kirkDouglas".downcase.titleize #=> "Kirkdouglas"

1
还有一个很好用的 gem titleize - zhon
6
标题化并不像看起来那么简单,例如'hEy LoOK'会变成'H Ey Lo Ok'。 - James McMahon
8
有一个需要注意的问题,titleize 方法会完全去除某些字符,例如连字符(-),"who? - me".titleize => "Who? Me"。请注意不改变原意,使翻译更加通俗易懂。 - pixelearth
对我来说,它将所有的破折号转换为单独的空格。 - boulder_ruby

230
尝试这个:
puts 'one TWO three foUR'.split.map(&:capitalize).join(' ')

#=> One Two Three Four

或者

puts 'one TWO three foUR'.split.map(&:capitalize)*' '

9
默认情况下,split方法按空格进行分割,因此您可以使其更短:'one TWO three foUR'.split.map(&:capitalize).join(' ') - Mischa
1
@waltee,你能解释一下.map(&:capitalize)的含义吗?或者至少告诉我在哪里可以找到相关文档?我找不到任何相关信息。另外,第二段代码末尾的*' '是什么意思? - macsplean
7
&:method 语法在 map 中的使用是一种简洁的方式,可以对数组中的每个元素调用一个方法。接着你可以调用 join 方法将该数组转换成字符串。* ' ' 是另外一种调用 join 的方式。你可以将其理解为将数组中的元素相乘以创建一个字符串。 - Andrew

38

"hello world".titleize会输出"Hello World"。


这将输出“ One Two Three Fo Ur”,这与此情况下所需的输出不同,但在其他情况下可能是需要的。 - Rick Smith
3
这不是一个 Ruby 方法,而是 ActiveSupport(Rails)在 v2.2.1 版本中引入的一种方法。 - Zack Burt

25

另一种选择是使用正则表达式和gsub,它需要一个块:

'one TWO three foUR'.gsub(/\w+/, &:capitalize)

2
这个保留了单词间的破折号等。 - Beer Me
7
.gsub(/\b\w/, &:capitalize)可以保留单词内原本的大写格式,例如:"Jane mcCollins"。 - user3680688
1
使用 [[:alpha:]] 而不是 \w 可以使其支持 Unicode。 - Adobe

5
"hello world".split.each{|i| i.capitalize!}.join(' ')

1
如果你不使用变量,就没有理由使用感叹号(!)运算符。 - boulder_ruby
2
@boulder_ruby 如果你不使用变量,就没有理由使用感叹号操作符这种说法是不正确的。每次迭代 each 块时的返回值都会被丢弃。 实际上是在原地修改了 split 生成的字符串。如果没有 ,则 capitalize 会为每个迭代创建一个新的首字母大写的字符串,然后立即将其丢弃。最终结果将是 "hello world",与原始字符串完全相同。有了 split 的每个字符串都被更改,因此 each 的结果是一个首字母大写的字符串数组。 - user513951
1
是的,你只需要使用 map。不过这个 hack 很有趣。分数。 - boulder_ruby

5

1
String#capitalize 方法会将第一个字母大写,而将其余部分小写。对于像 "McGee" 这样的名称来说,这是不期望的结果,但在某些情况下它也有一定的用处。 - Br.Bill

1
如果您想将数组中每个单词的首字母大写,只需输入以下代码:

array_name.map(&:capitalize)


1

我曾经用过这个来解决类似的问题:

'catherine mc-nulty joséphina'.capitalize.gsub(/(\s+\w)/) { |stuff| stuff.upcase }

这个处理程序解决了我在尝试之前的答案中遇到的以下奇怪情况:

  • 非单词字符,如 -
  • 常见于名字中的重音字符,如 é
  • 字符串中间的大写字符

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接