Перетворення зміїного чохла на нижній чохол для верблюдів (lowerCamelCase)


80

Що було б хорошим способом перетворити зі зміїної справи ( my_string) на нижню верблюдню справу (myString) у Python 2.7?

Очевидним рішенням є розділення підкресленням, написання великих літер кожним словом, крім першого, та об’єднання.

Однак мені цікаво щодо інших, більш ідіоматичних рішень чи способу використання цього RegExpдля досягнення (з яким-небудь модифікатором регістру?)


Наскільки мені відомо, цього неможливо досягти нестандартно. Ви намагалися впровадити власне рішення?
Frédéric Hamidi

відредагував своє запитання, я знаю, що немає вбудованого, я хотів знайти гарну реалізацію
luca

Я не думаю, що це питання якимось чином не відповідає темі.
0xc0de

Відповіді:


148
def to_camel_case(snake_str):
    components = snake_str.split('_')
    # We capitalize the first letter of each component except the first one
    # with the 'title' method and join them together.
    return components[0] + ''.join(x.title() for x in components[1:])

Приклад:

In [11]: to_camel_case('snake_case')
Out[11]: 'snakeCase'

11
До яких інших типів даних може бути застосований camelCasing?
jbaiter

20
Ну, це насправді не ідіоматичний Python, який, як правило, дотримується принципу "Простіше просити прощення, ніж дозволу". З> 3.5 ви можете додавати підказки щодо типу, якщо ви хочете безпеку типу, але перевірка типу за допомогою if-else для таких чітких функцій, як ця (що ще можна зробити camelCase, крім рядків?) - це просто поганий стиль і надмірна багатослів'я в моїй книзі.
jbaiter

2
Я просто хотів приєднати тут jbaiter. Це не відповідальність за те, to_camel_caseщоб забезпечити введення рядком, це відповідальність за виклик коду. Передача не-рядка спричинить виняток, що добре. Ось для чого винятки.
kylebebak

@stelios Навіть не. А як щодо порожніх рядків? А що б ви зробили інакше? Тому що таким чином ви повертаєте a None. Ви не можете запобігти жодній помилці. Якщо ви спробуєте, ви в кінцевому підсумку лише засліните його джерело. Це Python, а не Java. Вам не потрібно уникати винятків, ви повинні лікувати їх.
Нуно Андре

1
Трохи кутовий випадок, але якщо ви очікуєте _barстати barзамість нього Bar, то зробіть невелику components = snake_str.lstrip('_').split('_')
підгонку

15

Ось ще одна думка, яка працює лише в Python 3.5 і вище:

def camel(snake_str):
    first, *others = snake_str.split('_')
    return ''.join([first.lower(), *map(str.title, others)])

Не використовуйте розуміння списку, коли це робить генератор (тобто, join(...)це краще, ніж join([...])тут, оскільки він працює без створення списку).
Ведран Шего,

2
Ви абсолютно праві, однак це не застосовується в даному конкретному випадку, оскільки те, що передається joinметоду, - це не розуміння, а звичайний список. Якщо ви хочете уникнути створення списку в пам'яті, який ви могли б використовувати itertools.chain, але тоді, якщо вас турбує слід пам'яті при перетворенні змії у верблюд, у вас набагато більші проблеми. ;-)
Беріслав Лопач

Вибачте, я неправильно прочитав (бо я тут шукав PascalCase замість camelCase). Ні, це нормально.
Ведран Шего,

8

Обов'язковий однокласний:

import string

def to_camel_case(s):
    return s[0].lower() + string.capwords(s, sep='_').replace('_', '')[1:] if s else s

Цей метод виявляється невдалим при підкресленні літер (перша буква опускається).
siebz0r

3
Ще коротше: return re.sub(r'_([a-z])', lambda x: x.group(1).upper(), name) (див. Тут)
Матьє Родіч

5
>>> snake_case = "this_is_a_snake_case_string"
>>> l = snake_case.split("_")
>>> print l[0] + "".join(map(str.capitalize, l[1:]))
'thisIsASnakeCaseString'

4

ще один лайнер

def to_camel_case(snake_string):
    return snake_string.title().replace("_", "")

4
Перший символ - верхній регістр.
SiHa

4

Трохи пізно до цього, але я знайшов це на / r / python пару днів тому:

pip install pyhumps

а потім ви можете просто зробити:

import humps

humps.camelize('jack_in_the_box')  # jackInTheBox
# or
humps.decamelize('rubyTuesdays')  # ruby_tuesdays
# or
humps.pascalize('red_robin')  # RedRobin

1

Спираючись на відповідь Стіва, ця версія повинна працювати:

def to_camel_case(snake_case_string):
    titleCaseVersion =  snake_case_string.title().replace("_", "")
    camelCaseVersion = titleCaseVersion[0].lower() + titleCaseVersion[1:]
    return camelCaseVersion

1

Ось рішення із використанням регулярних виразів:

import re

def snake_to_camel(text):
    return re.sub('_([a-zA-Z0-9])', lambda m: m.group(1).upper(), text)


0

Без використання розуміння списку:

def snake_to_camel_case(text_snake):
    return '{}{}'.format(
        text_snake[:1].lower(),
        text_snake.title().replace('_', '')[1:],
    )

0

Тож мені потрібно було перетворити цілий файл з купою параметрів справи змії у верблюд. Рішення Матьє Родіка працювало найкраще. Дякую.

Ось невеликий сценарій для використання його у файлах.

import re

f = open("in.txt", "r")
words = f.read()

def to_camel_case3(s):
    return re.sub(r'_([a-z])', lambda x: x.group(1).upper(), s)

f = open("out.txt", "w")
f.write(to_camel_case3(words))

0
def toCamel(snake)
    return ''.join( word.capitalize()
                    for word in snake.split('_') )

Дозвольте уникнути нижнього підкреслення попереднім підкресленням (наприклад, "Escaped__snake" стане "Escaped_Snake", тоді як "normal_snake" стане "UsualSnake". Включіть тернарний тест для порожнього.

def toCamel(escaped_snake)
    return ''.join( (word.capitalize(), '_')[word=='')
                    for word in escaped_snake.split('_') )

Не використовуйте великі літери в першому сегменті (тобто "tHERE_is_a_snake" стає "thereIsASnake")

def toCamel(esCAPed_snake)
    words = esCAPed_snake.split('_')
    return words[0].lower() + ''.join( (word.capitalize(), '_')[word=='')
                                       for word in words[1:] )

-2

Також можна tocamelcaseлегко перетворити з футляра змії на футляр верблюда.

Встановити

$ pip install tocamelcase

а потім ви можете використовувати його так:

import tocamelcase

print(tocamelcase.convert("non_camel_case"))
# -> non_camel_case → NonCamelCase

Існує також decamelizeте, що є інверсом цього модуля.


Це PascalCase, тому навіть назва модуля вводить в оману.
stasdeep
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.