В рамках универсального перевода строки в snake_case такой подход с регулярками, наверное, самый хороший вариант:
import re
def to_snake_case(s: str) -> str:
s = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', s)
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s).replace('-', '_').lower()🧐 Как это работает?
1️⃣
re.sub('(.)([A-Z][a-z]+)', r'\1_\2', s) заменяет каждую заглавную букву, предшествующую строчной, на ту же букву, но с подчеркиванием перед ней.2️⃣
re.sub('([a-z0-9])([A-Z])', r'\1_\2', s) меняет каждую заглавную букву, предшествующую строчной или цифре, на эту же букву, но с подчеркиванием перед ней.3️⃣ Потом всё приводим к нижнему регистру и заменяем дефис на подчеркивание.
Но давайте выйдем за рамки алгозадачи и посмотрим, как такую проблему решать в реальности. Если в проекте используется Pydantic, то там всё это давно написано, протестировано на миллионах строк кода и лежит прямо в коробке:
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel, to_snake
class FrontendData(BaseModel):
model_config = ConfigDict(
alias_generator=to_camel, # Автоматом ждет camelCase на вход
populate_by_name=True
)
python_talk: str # В коде работаем с православным snake_caseПод капотом лежат вылизанные алгоритмы, которые учитывают краевые случаи, нестандартные разделители и больные фантазии разработчиков смежных систем.
А если Pydantic в проекте нет, есть микро-библиотеки вроде inflection, которые делают то же самое:
import inflection
inflection.underscore("CamelCaseAnd-kebab-case")
# -> 'camel_case_and_kebab_case'
inflection.camelize("python_talk", uppercase_first_letter=False)
# -> 'pythonTalk'Алгоритмы на регулярках знать полезно, чтобы пройти алгособес и понимать, как парсятся строки. А вот инструменты знать необходимо, чтобы не тащить в прод самописные велосипеды, которые неминуемо сломаются на первом же кривом payload'е.
#алгособес
Комментарии
0Комментариев пока нет.
Войдите, чтобы участвовать в обсуждении.