我在Ruby中使用gsub
得到了以下函数。
def class_to_endpoint(klass)
klass.name.split('::').last.
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
gsub(/([a-z\d])([A-Z])/,'\1_\2').
tr("-", "_").
downcase
end
如何在Python中实现这一点?请帮帮我
在irb控制台上试过这个并且我可以给出一些例子,基本上在camelcase语法中添加一个下划线bw每个单词
UserProfile
- > user_profile
LastModifiedTime
- > last_modified_time
User-Profile
- > user_profile
答案: 我想这就是我想要的 - > Elegant Python function to convert CamelCase to snake_case?
从上面的链接复制并修改了一下
def class_to_endpoint(name):
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).replace('-', '_').lower()
答案 0 :(得分:2)
我们的想法是获取一个类并将其 CamelCase 名称转换为 snake_case 名称。
让我试着解释一下:
klass.name.split('::').last
ruby中的命名空间是通过在模块或其他类中嵌套类来实现的。例如:
module API
class Service2URLMapper
end
end
Service2URLMapper
可以引用API::Service2URLMapper
。这是这里给出的方法。按::
拆分并获取最后一个元素将为您提供没有命名空间前缀的类的名称。在这种情况下Service2URLMapper
。
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
如果序列后面跟一个小写字母,这将在最后一个大写字母的位置用_
分割两个或多个大写字母的任何序列。例如:
"Service2URLMapper".gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2') # => "Service2URL_Mapper"
下一部分是
gsub(/([a-z\d])([A-Z])/,'\1_\2')
如果之前是一个小写字母,后面跟一个大写字母,它会在数字之后进行类似的分割:
"Service2URL_Mapper".gsub(/([a-z\d])([A-Z])/,'\1_\2') # => "Service2_URL_Mapper"
python中的两个正则表达式应该是相同的。
之后,tr("-", "_")
只会将-
替换为_
。我不知道谁在他们的班级名称中使用破折号,但显然作者认为这是必要的。
最后downcase
只是做你期望的事。
所以行动中的一切都给了我们:
class_to_endpoint(API::Service2URLMapper) # => "service2_url_mapper"
答案 1 :(得分:2)
python one-liner将完成这项工作。
>>> import re
>>> s = ['LastModifiedTime','UserProfile','User-Profile']
>>> [re.sub(r'(^|([a-z])\W?)([A-Z])', lambda m: m.group(2)+'_'+ m.group(3).lower() if m.group(1) else m.group(3).lower(), i) for i in s]
['last_modified_time', 'user_profile', 'user_profile']