【问题标题】:Converting upper-case string into title-case using Ruby使用 Ruby 将大写字符串转换为标题大小写
【发布时间】:2009-11-24 17:30:17
【问题描述】:

我正在尝试将 Ruby 中的全大写字符串转换为小写字符串,但每个单词的第一个字符都是大写的。示例:

将“我的字符串”转换为“我的字符串”。

我知道我可以使用 .downcase 方法,但这会使所有内容都小写(“我的字符串在这里”)。我正在扫描文件中的所有行并进行此更改,那么我可以通过 ruby​​ 使用正则表达式来实现此目的吗?

谢谢!

【问题讨论】:

标签: ruby string


【解决方案1】:

如果您使用的是 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 不能很好地处理首字母缩略词,会将 camelCaseStrings 拆分为单独的单词。这可能是可取的,也可能不是可取的:

"Always use SSL on your iPhone".titleize
# => "Always Use Ssl On Your I Phone"

您可以(部分)通过添加“首字母缩略词”来解决这个问题:

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

【讨论】:

  • 完美答案,其他人都在重新发明轮子,而您正在使用提供的轮子,这是使用 Ruby on Rails 的要点
  • 请注意他的回答是关于 Rails 的。如果您使用的是 Rails,这个答案是最好的。但是,如果您只使用 Ruby,您可能不想要求整个 ActiveSupport 库只是为字符串命名。这里有效率方面的考虑。但是,当我这样做的时候,为什么他们没有给英国人“titleise”?
  • titleize 适合这个用例(大写全大写字符串),但混合大小写有一个陷阱:'jOhn'.titleize # => "J Ohn"。这只是咬我。
  • @mjnissim 如果你只需要Rails string inflections,你可以require 'active_support/core_ext/string/inflections',不是吗?
  • @Dennis 是的,我认为你是对的。很好的评论,谢谢。因此,在没有 Rails 的情况下,首先使用require 'active_support/core_ext/string/inflections',然后使用.titleize。这将只需要所需的东西 - 更高效。
【解决方案2】:
"HELLO WORLD HOW ARE YOU".gsub(/\w+/) do |word|
  word.capitalize
end
#=> "Hello World How Are You"

【讨论】:

  • 优秀而简洁。说明: gsub 替换所有出现的事件。正则表达式表示“任何由单词字符组成的子字符串(\w'), followed by 0 or more word characters (+)." Note that this can be a one-liner if you use {|word| word.capitalize} instead of do` 和 end - 这只是一个偏好问题。
  • 您还可以轻松添加条件语句以仅将某些单词大写 - if wordArray.include?(word) word.capitalize else word(添加换行符以运行)
  • 单行在 erb 模板循环中对我很有效,我想在保留连字符的同时大写文件名列表:"name-another-third".gsub(/\w+/){|word| word.capitalize} => "Name-Another-Third
  • 对于那些寻找单线的人 - 你也可以这样做"HELLO WORLD".gsub(/\w+/, &:capitalize)
【解决方案3】:

在尝试提出自己的方法(包括在下面以供参考)时,我意识到存在一些非常讨厌的极端情况。最好还是使用Facets中已经提供的方法,最牛的Ruby库evar:

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” gem。

【讨论】:

  • 请注意,Facet 的titlecase 不会将任何字符从大写转换为小写。实际示例,"MY STRING HERE".titlecase 返回"MY STRING HERE"。您需要"MY STRING HERE".downcase.titlecase 才能获得请求的输出。
【解决方案4】:

来自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"] 的数组,最后我们通过join为每个元素加上一个空格(“”)将该数组转换回字符串。

    【讨论】:

    • 请注意,如果字符串包含换行符或制表符,这会将多个连续的空格合二为一并中断。
    【解决方案6】:
    "MY STRING HERE".titlecase
    

    可以完成这项工作(不过,它是 Rails gem 中的一种方法) http://apidock.com/rails/String/titlecase

    【讨论】:

    • 没有这样的标准方法#titlecase。如果这是在 gem 中实现的,也请参考它!
    【解决方案7】:

    Ruby 2.4.0+ 的 Unicode 感知标题:

    class String
      def titlecase
        split(/([[:alpha:]]+)/).map(&:capitalize).join
      end
    end
    
    >> "я только что посмотрел \"леди исчезает\", и это чума!".titlecase
    => "Я Только Что Посмотрел \"Леди Исчезает\", И Это Чума!"
    

    (基于https://stackoverflow.com/a/1792102/788700

    【讨论】:

      【解决方案8】:

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

      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
      

      【讨论】:

        【解决方案9】:

        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

        【讨论】:

          【解决方案10】:

          使用 ruby​​ 将句子中的每个单词大写,不使用正则表达式。因为不幸的是那些吓到我了

          class Book
              attr_accessor :title
              def title=(new_title)
                  result = []
                  words = new_title.split(' ')
                  words.each do |word|
                      capitalized = word[0].upcase + word[1..word.length].downcase
                      result.push(capitalized)
                  end
          
                  @title = result.join(' ')
              end
          end
          

          【讨论】:

            猜你喜欢
            • 2010-11-15
            • 2010-09-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多