使用Ruby将大写字符串转换为标题格式

59
我想在Ruby中将一个全大写的字符串转换为小写,但每个单词的第一个字符需要大写。示例:
将 "MY STRING HERE" 转换为 "My String Here"。
我知道可以使用 .downcase 方法,但那会使所有字符变成小写("my string here")。我正在扫描文件中的所有行并进行此更改,因此是否有正则表达式可以通过Ruby实现此功能?
谢谢!

相关问题:https://dev59.com/Nm035IYBdhLWcg3wHsOR - Andrew Grimm
这个回答解决了你的问题吗?在Ruby中将驼峰命名法转换为下划线命名法 - Eyeslandic
11个回答

103
如果你使用的是Rails(实际上只需要使用其中的ActiveSupport,这是Rails的一部分),你可以使用titleize
"MY STRING HERE".titleize
# => "My String Here"

如果您正在使用纯Ruby,但不介意加载少量的ActiveSupport,则可以先引用它:

require 'active_support/core_ext/string/inflections'
# => true
"MY STRING HERE".titleize
# => "My String Here"

注意:默认情况下,titleize 方法无法正确处理缩写词和驼峰式字符串,会将它们分割成单独的单词。这可能有利也可能不利。

"Always use SSL on your iPhone".titleize
# => "Always Use Ssl On Your I Phone"
你可以通过添加“缩写词”(“acronyms”)来(部分地)解决这个问题:
require 'active_support/core_ext/string/inflections' # If not using Rails
ActiveSupport::Inflector.inflections do |inflect|
  inflect.acronym 'SSL'
  inflect.acronym 'iPhone'
end
"Always use SSL on your iPhone".titleize
# => "Always Use SSL On Your IPhone"

对于那些使用英国皇家英语的人(或者拼写"titleize"有困难的人),没有.titleise的别名,但是你可以使用.titlecase代替。


7
完美的答案,其他人都在重新发明轮子,而你正在使用已提供的轮子,这是使用Ruby on Rails的主要优势之一。 - Michael Durrant
14
请注意,他回答的是关于Rails的问题。如果你正在使用Rails,这个答案是最好的。但是,如果你只是使用Ruby,为了将字符串标题化,你可能不想要求整个ActiveSupport库。这里有效率方面的考虑。顺便说一下,为什么他们没有为英国人提供“titleise”呢? - mjnissim
8
titleize 对于这种用例(将全大写字符串大写)很好,但对于混合大小写还有一个需要注意的地方:'jOhn'.titleize # => "J Ohn"。这让我有些不爽。 - fabi
1
如果你只需要Rails字符串转换,你可以使用require 'active_support/core_ext/string/inflections',对吗? - Dennis
1
@Dennis 是的,我认为你是对的。好评论,谢谢。所以当没有使用Rails时进行标题化,首先需要 require 'active_support/core_ext/string/inflections' 然后使用 .titleize。这将只需要所需的内容-更有效率。 - mjnissim
问题是关于 Ruby,而不是 Rails。 - Connor Leech

61
"HELLO WORLD HOW ARE YOU".gsub(/\w+/) do |word|
  word.capitalize
end
#=> "Hello World How Are You"

6
优秀而简洁。说明: gsub替换所有出现的内容。正则表达式意思是“包含一个单词字符(\w),后面跟着零个或多个单词字符(+)” 的任何子字符串。请注意,如果使用{|word| word.capitalize}代替doend,这可以成为一行代码 - 这只是个人偏好。 - Nathan Long
1
您还可以轻松地添加一个条件语句,以仅大写某些单词 - if wordArray.include?(word)word.capitalize else word(添加换行符以运行)。 - Nathan Long
2
这个一行代码对我很有用,它可以在erb模板循环中对文件名列表进行大写处理,同时保留连字符:"name-another-third".gsub(/\w+/){|word| word.capitalize} => "Name-Another-Third"。 - Dave Everitt
7
想要一句话解释的话,也可以使用 "HELLO WORLD".gsub(/\w+/, &:capitalize) 这段代码。它的作用是将字符串中所有的单词首字母大写。 - Nick

37

尝试编写自己的方法时(参考下文),我意识到有些非常棘手的情况。最好使用已经提供在 Facets 中的方法,这是最好的 Ruby 库之一:

require 'facets/string/titlecase'

class String
  def titleize
    split(/(\W)/).map(&:capitalize).join
  end
end

require 'test/unit'
class TestStringTitlecaseAndTitleize < Test::Unit::TestCase
  def setup
    @str = "i just saw \"twilight: new moon\", and man!   it's crap."
    @res = "I Just Saw \"Twilight: New Moon\", And Man!   It's Crap."
  end
  def test_that_facets_string_titlecase_works
    assert_equal @res, @str.titlecase
  end
  def test_that_my_own_broken_string_titleize_works
    assert_equal @res, @str.titleize # FAIL
  end
end

如果你想要符合典型写作风格指南的东西(即不会将“and”之类的单词大写),在GitHub上有几个“titleize”宝石。


请注意,Facet的titlecase不会将任何字符从大写转换为小写。实际示例"MY STRING HERE".titlecase返回"MY STRING HERE"。您需要使用"MY STRING HERE".downcase.titlecase才能获得所需的输出。 - Dan

9

From ActiveSupport

"MY STRING HERE".gsub(/\b('?[a-z])/) { $1.capitalize }

如果您正在使用Rails/ActiveSupport,该方法已经免费提供。

5
string = "MY STRING HERE"
string.split(" ").map {|word| word.capitalize}.join(" ")

这是个如下所示的操作步骤: .split(" ")会将字符串以空格为分隔符进行拆分,从而得到一个数组,例如["my", "string", "here"]。接着map方法对数组中的每个元素进行迭代,将其赋给临时变量word,并对其调用capitalize方法。此时,我们得到了一个数组["My", "String", "Here"],最后通过将每个元素使用空格(" ")连接起来,将该数组转换回字符串。

7
请注意,这将把多个连续的空格变成一个空格,并且如果字符串包含换行符或制表符,则会产生错误。 - sepp2k

3

针对 Ruby 2.4.0+ 的 Unicode 意识标题大小写:

class String
  def titlecase
    split(/([[:alpha:]]+)/).map(&:capitalize).join
  end
end

>> "я только что посмотрел \"леди исчезает\", и это чума!".titlecase
=> "Я Только Что Посмотрел \"Леди Исчезает\", И Это Чума!"

(基于https://dev59.com/2HI-5IYBdhLWcg3wkJIA#1792102)

(基于 https://dev59.com/2HI-5IYBdhLWcg3wkJIA#1792102)

2

1
没有标准的 #titlecase 方法。如果这个方法已经在 gem 中实现了,请同时引用它! - Itay Grudev

1

为了捕捉任何边缘情况,例如:

str = "rUby on rAils"

不要使用:

str.titleize

输出结果:R Uby On R Ails

应使用:

str.downcase.titleize

输出结果:Ruby On Rails


0

我尝试改进代码...准备接受批评和建议。

class Book
    attr_accessor :title
    def title=(new_title)
    notcap=%w(and the a in of an)
    str=''
    new_title.gsub(/(\w|\s)\w+/) do |word|
        word.strip!
        if not notcap.include? word
               word.capitalize! 
        end
       str += ' ' + word 
    end
    str.strip!
    str = str[0].upcase + str[1..-1]
    @title = str
   end
end

0

Ruby核心本身不支持将字符串从大写(单词)转换为首字母大写的单词。

因此,您需要自己实现或使用现有的gem。

有一个名为lucky_case的小型Ruby gem,它允许您轻松地将字符串从10多种支持的情况之一转换为另一种情况:

require 'lucky_case'

# to get capital word case as string
LuckyCase.capital_word_case('MY STRING HERE')    # => 'My String Here'
# or the opposite way
LuckyCase.upper_word_case('Capital Word Case')   # => 'MY STRING HERE'

如果你想的话,甚至可以对String类进行猴子补丁:

require 'lucky_case/string'

'MY STRING HERE'.capital_word_case  # => 'My String Here'
'MY STRING HERE'.capital_word_case! # => 'My String Here' and overwriting original

请查看官方存储库以获取更多示例和文档:

https://github.com/magynhard/lucky_case


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