【问题标题】:Converting camel case to underscore case in ruby在ruby中将骆驼大小写转换为下划线大小写
【发布时间】:2010-12-03 08:29:34
【问题描述】:

有没有现成的函数可以将驼峰字符串转换为下划线分隔的字符串?

我想要这样的东西:

"CamelCaseString".to_underscore      

返回“camel_case_string”。

...

【问题讨论】:

  • 仅供参考:小写和下划线是“官方”称为蛇形大小写
  • 在引号中看到“正式”很奇怪,然而,这是描述它的最佳方式。
  • 由于某种原因,我看到蛇盒方法丢失。导轨 4.

标签: ruby-on-rails ruby string formatting case-conversion


【解决方案1】:

我在 rake 任务中运行 "CamelCaseString".underscore 时遇到问题。这对我有帮助:

ActiveSupport::Inflector.underscore "CamelCaseString"
=> "camel_case_string"

当然,你需要 ActiveSupport

【讨论】:

    【解决方案2】:

    如果还包含空格,则为 CamelCases 使用短单行线(如果中间有一个带有小开头字母的单词,则无法正常工作):

    a = "Test String"
    a.gsub(' ', '').underscore
      
      => "test_string"
    

    编辑:正如@dft 指出的那样,这种方法不是Ruby 的一部分,而是Rails 的一部分。

    【讨论】:

    • underscore 不是 ruby​​ 的一部分
    【解决方案3】:

    我想要这个:

    class String
    
      # \n returns the capture group of "n" index
      def snakize
        self.gsub(/::/, '/')
        .gsub(/([a-z\d])([A-Z])/, "\1_\2")
        .downcase
      end
    
      # or
    
      def snakize
        self.gsub(/::/, '/')
        .gsub(/([a-z\d])([A-Z])/) do
          "#{$1}_#{$2}"
        end
        .downcase
      end
    
    end
    

    String 类的猴子补丁。有些类以两个或多个大写字母开头。

    【讨论】:

    【解决方案4】:

    ruby 核心本身不支持将字符串从(大写)驼峰式大小写转换为(也称为帕斯卡大小写)到下划线(也称为蛇形大小写)。

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

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

    require 'lucky_case'
    
    # convert to snake case string
    LuckyCase.snake_case('CamelCaseString')      # => 'camel_case_string'
    # or the opposite way
    LuckyCase.pascal_case('camel_case_string')   # => 'CamelCaseString'
    

    如果你愿意,你甚至可以修改 String 类:

    require 'lucky_case/string'
    
    'CamelCaseString'.snake_case  # => 'camel_case_string'
    'CamelCaseString'.snake_case! # => 'camel_case_string' and overwriting original
    

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

    https://github.com/magynhard/lucky_case

    【讨论】:

      【解决方案5】:

      如果有人在寻找需要将下划线应用于带空格的字符串并希望将它们转换为下划线的情况下,您可以使用类似这样的东西

      'your String will be converted To underscore'.parameterize.underscore
      #your_string_will_be_converted_to_underscore
      

      或者只使用 .parameterize('_') 但请记住,这个已被弃用

      'your String will be converted To underscore'.parameterize('_')
      #your_string_will_be_converted_to_underscore
      

      【讨论】:

        【解决方案6】:

        你可以使用

        "CamelCasedName".tableize.singularize
        

        或者只是

        "CamelCasedName".underscore
        

        两种选择方式都会产生"camel_cased_name"。您可以查看更多详细信息here

        【讨论】:

        • 这是 ActiveSupport::Inflector 实现的一部分,没有它,您将无法使用那些字符串扩展(在纯 irb 控制台中尝试:“ThisCamelCaseString”.underscore,然后需要 'active_support/inflector'再试一次)
        • OP 的标签上写着“ruby-on-rails”
        【解决方案7】:

        查看Ruby Facetssnakecase

        处理以下情况,如下图:

        "SnakeCase".snakecase         #=> "snake_case"
        "Snake-Case".snakecase        #=> "snake_case"
        "Snake Case".snakecase        #=> "snake_case"
        "Snake  -  Case".snakecase    #=> "snake_case"
        

        发件人:https://github.com/rubyworks/facets/blob/master/lib/core/facets/string/snakecase.rb

        class String
        
          # Underscore a string such that camelcase, dashes and spaces are
          # replaced by underscores. This is the reverse of {#camelcase},
          # albeit not an exact inverse.
          #
          #   "SnakeCase".snakecase         #=> "snake_case"
          #   "Snake-Case".snakecase        #=> "snake_case"
          #   "Snake Case".snakecase        #=> "snake_case"
          #   "Snake  -  Case".snakecase    #=> "snake_case"
          #
          # Note, this method no longer converts `::` to `/`, in that case
          # use the {#pathize} method instead.
        
          def snakecase
            #gsub(/::/, '/').
            gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
            gsub(/([a-z\d])([A-Z])/,'\1_\2').
            tr('-', '_').
            gsub(/\s/, '_').
            gsub(/__+/, '_').
            downcase
          end
        
          #
          alias_method :underscore, :snakecase
        
          # TODO: Add *separators to #snakecase, like camelcase.
        
        end
        

        【讨论】:

        • 它不适用于带有特殊字符的字符串。例如:"Dumb Penguin's Egg".snakecase # => "dumb_penguin's_egg"
        • 这就是我要找的,谢谢@abram
        【解决方案8】:

        有一个名为“下划线”的 Rails 内置方法可以用于此目的

        "CamelCaseString".underscore #=> "camel_case_string" 
        

        'underscore' 方法通常可以被认为是 'camelize' 的逆方法

        【讨论】:

        • 未定义方法 `underscore' for "...":String
        • 这是一种 ActiveSupport 方法
        【解决方案9】:

        Rails' ActiveSupport 使用以下命令为字符串添加下划线:

        class String
          def underscore
            self.gsub(/::/, '/').
            gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
            gsub(/([a-z\d])([A-Z])/,'\1_\2').
            tr("-", "_").
            downcase
          end
        end
        

        然后你可以做一些有趣的事情:

        "CamelCase".underscore
        => "camel_case"
        

        【讨论】:

        • 如果您将tr("-","_") 更改为tr("- ","_")(第一个参数添加空格),这也会将空格变成下划线。另外,我认为您甚至不需要包含self.,或者至少它适用于我在 Ruby 1.9.3 下。
        • require 'active_support/core_ext/string'
        • 下划线函数Active使用:github.com/rails/rails/blob/…
        • 下划线是 Rails 的方法,不是 ruby​​,见 apidock.com/rails/String/underscore
        • @S.Yadav true 该方法是Rails,因此默认情况下您不能调用下划线,但是通过提供使用的代码并引用rails作为源,这个答案对于ruby来说是一个很好的答案,它说你可以包含 rails,或者只包含 rails 团队编写并测试过的这个函数。
        【解决方案10】:

        单线 Ruby 实现:

        class String
           # ruby mutation methods have the expectation to return self if a mutation occurred, nil otherwise. (see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-gsub-21)
           def to_underscore!
             gsub!(/(.)([A-Z])/,'\1_\2')
             downcase!
           end
        
           def to_underscore
             dup.tap { |s| s.to_underscore! }
           end
        end
        

        所以"SomeCamelCase".to_underscore # =>"some_camel_case"

        【讨论】:

        • 其他解决方案怎么不是纯红宝石?
        • 哦,嘘...谢谢 - 我对写作比阅读更感兴趣。结果 - Rails 上的链接让我认为其他 sn-ps 是特定于 Rails 的。改变答案...
        • 我的编辑中还有另一个错误,看来我无法修复它。这是更正后的代码:gist.github.com/4027440
        • 您可能需要考虑 /([^A-Z])([A-Z]+)/ 来处理 "ALLCAPS" -> "allcaps" 而不是 "a_ll_ca_ps"
        • 这实际上是一个 10 班轮!
        【解决方案11】:

        接收器转换为蛇盒:http://rubydoc.info/gems/extlib/0.9.15/String#snake_case-instance_method

        这是 DataMapper 和 Merb 的支持库。 (http://rubygems.org/gems/extlib)

        def snake_case
          return downcase if match(/\A[A-Z]+\z/)
          gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
          gsub(/([a-z])([A-Z])/, '\1_\2').
          downcase
        end
        
        "FooBar".snake_case           #=> "foo_bar"
        "HeadlineCNNNews".snake_case  #=> "headline_cnn_news"
        "CNN".snake_case              #=> "cnn"
        

        【讨论】:

          【解决方案12】:

          这是Rails does it

             def underscore(camel_cased_word)
               camel_cased_word.to_s.gsub(/::/, '/').
                 gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
                 gsub(/([a-z\d])([A-Z])/,'\1_\2').
                 tr("-", "_").
                 downcase
             end
          

          【讨论】:

          • 最好将操作数作为方法参数,而不是侵入核心 String 类。
          • 不同意 - 最好让它像应有的那样在类上运行,否则您将不得不将其粘贴在模块中并记住将其包含在您需要的任何地方。跨度>
          • 这个方法也是 Rails 3 字符串的一部分 :)
          • 如果我可以加入这场辩论——最好让它侵入字符串类你包含它=)。
          猜你喜欢
          • 1970-01-01
          • 2016-08-07
          • 2014-10-30
          • 1970-01-01
          • 2021-04-27
          • 1970-01-01
          • 1970-01-01
          • 2019-06-12
          • 1970-01-01
          相关资源
          最近更新 更多