在Ruby中将字符串从Snake_大小写转换为驼峰大小写

我正在尝试将名称从Snake Case转换为Camel Case.有内置的方法吗?

例如:"app_user""AppUser"

(我有一个"app_user"的字符串,我想将其转换为模型AppUser)。

121878 次浏览

如果您使用的是Rails,那么字符串#camelize就是您要寻找的。

  "active_record".camelize                # => "ActiveRecord"
"active_record".camelize(:lower)        # => "activeRecord"

如果你想得到一个实际的类,你应该在其上使用字符串#constantize

"app_user".camelize.constantize

如果使用滑轨,请使用classify。它可以很好地处理边缘情况。

"app_user".classify # => AppUser
"user_links".classify   # => UserLink

注意:

此答案特定于问题中给出的描述(不特定于问题标题)。如果尝试将字符串转换为驼峰式大小写,则应使用塞尔吉奥的答案。提问者陈述他想要将app_user转换为AppUser(而不是App_user),因此得到以下回答。

来源:_农行_0

出于学习目的:

class String
def camel_case
return self if self !~ /_/ && self =~ /[A-Z]+.*/
split('_').map{|e| e.capitalize}.join
end
end


"foo_bar".camel_case          #=> "FooBar"

对于小写变量:

class String
def camel_case_lower
self.split('_').inject([]){ |buffer,e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
end
end


"foo_bar".camel_case_lower          #=> "fooBar"

我在这里寻找你的问题的反面,从骆驼案到蛇案。使用下划线表示(不去氨基):

AppUser.name.underscore # => "app_user"

或者,如果已有驼峰式大小写字符串:

"AppUser".underscore # => "app_user"

或者,如果您想要获得表名,这可能是您想要使用snake的原因:

AppUser.name.tableize # => "app_users"

这里列出的大多数其他方法都是特定于Rails的。如果你想用纯Ruby来做这件事,下面是我想出的最简洁的方法(感谢@Ulysse-BN的改进建议)

x="this_should_be_camel_case"
x.gsub(/(?:_|^)(\w)/){$1.upcase}
#=> "ThisShouldBeCamelCase"

这个怎么样?

"hello_world".split('_').collect(&:capitalize).join #=> "HelloWorld"

在这里的评论中找到:分类Ruby字符串

韦恩·康拉德的评论

纯Ruby解决方案的基准测试

我想用纯Ruby代码来做这件事,我考虑了所有的可能性,如下:

  • 大写和GSUB

    'app_user'.capitalize.gsub(/_(\w)/){$1.upcase}
    
  • split and map using & shorthand (thanks to user3869936’s answer)

    'app_user'.split('_').map(&:capitalize).join
    
  • split and map (thanks to Mr. Black’s answer)

    'app_user'.split('_').map{|e| e.capitalize}.join
    

And here is the Benchmark for all of these, we can see that gsub is quite bad for this. I used 126 080 words.

                              user     system      total        real
capitalize and gsub  :      0.360000   0.000000   0.360000 (  0.357472)
split and map, with &:      0.190000   0.000000   0.190000 (  0.189493)
split and map        :      0.170000   0.000000   0.170000 (  0.171859)

在这里补充更多的答案,我感到有点不安。我决定采用最易读、最简单的纯Ruby方法,而不考虑来自@Ulysse-BN的好的基准测试。虽然:class模式是@user3869936的副本,但:method模式我在这里没有看到任何其他答案。

  def snake_to_camel_case(str, mode: :class)
case mode
when :class
str.split('_').map(&:capitalize).join
when :method
str.split('_').inject { |m, p| m + p.capitalize }
else
raise "unknown mode #{mode.inspect}"
end
end

结果是:

[28] pry(main)> snake_to_camel_case("asd_dsa_fds", mode: :class)
=> "AsdDsaFds"
[29] pry(main)> snake_to_camel_case("asd_dsa_fds", mode: :method)
=> "asdDsaFds"

扩展字符串以添加Camelize

在纯Ruby中,可以使用从Rails.camelize中提取的代码来扩展String类。

class String
def camelize(uppercase_first_letter = true)
string = self
if uppercase_first_letter
string = string.sub(/^[a-z\d]*/) { |match| match.capitalize }
else
string = string.sub(/^(?:(?=\b|[A-Z_])|\w)/) { |match| match.downcase }
end
string.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.gsub("/", "::")
end
end

Ruby核心本身不支持将字符串从Snake大小写转换为(上)Camel大小写(也称为Pascal大小写)。

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

有一个名为幸运_案件的小Ruby gem,它允许您轻松地将字符串从10+支持的任何情况转换为另一种情况:

require 'lucky_case'


# to get upper camel case (pascal case) as string
LuckyCase.pascal_case('app_user') # => 'AppUser'
# to get the pascal case constant
LuckyCase.constantize('app_user') # => AppUser
# or the opposite way
LuckyCase.snake_case('AppUser')   # => app_user

如果需要,您甚至可以对String类进行Monkey修补:

require 'lucky_case/string'


'app_user'.pascal_case # => 'AppUser'
'app_user'.constantize # => AppUser
# ...

查看官方存储库中的更多示例和文档:

https://github.com/magynhard/lucky_case.