Ruby Преобразование строки в undescore, избегайте «/» в результирующей строке

У меня есть класс с интервалом между именами..

"CommonCar::RedTrunk"

Мне нужно преобразовать его в строку с подчеркиванием "common_car_red_trunk", но когда я использую

"CommonCar::RedTrunk".underscore, вместо этого я получаю "common_car/red_trunk".

Есть ли другой способ выполнить то, что мне нужно?

Не будучи членом сообщества Rails, я бы подумал, что to_snake_case будет более информативным именем, чем underscore.

Cary Swoveland 18.12.2020 20:45

@CarySwoveland, аминь, брат. :-)

jeffdill2 07.09.2022 16:54
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
2
241
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Решения:

"CommonCar::RedTrunk".gsub(':', '').underscore

или:

"CommonCar::RedTrunk".sub('::', '').underscore

или:

"CommonCar::RedTrunk".tr(':', '').underscore

Альтернативный:

Или переверните любой из них и сделайте сначала underscore(), а затем любой метод, который вы хотите использовать, чтобы заменить «/» на «_».

Объяснение:

Хотя все эти методы выглядят в основном одинаково, есть небольшие различия, которые могут быть очень важными.

Суммируя:

  • gsub() — использует регулярное выражение для сопоставления с образцом, поэтому он находит любое вхождение ":" и заменяет его на "".

  • sub() – использует регулярное выражение для сопоставления с образцом, аналогично gsub(), за исключением того, что оно находит только первое вхождение ("g" в gsub() означает "глобальный"). Вот почему при использовании этого метода необходимо было использовать "::", иначе остался бы один ":". Имейте в виду, что этот метод будет работать только с пространством имен с одним вложением. Значение "CommonCar::RedTrunk::BigWheels" было бы преобразовано в "CommonCarRedTrunk::BigWheels".

  • tr() — использует строковые параметры как массивы замен одного символа. В этом случае, поскольку мы заменяем только один символ, он будет работать так же, как gsub(). Однако, если вы хотите заменить «on» на «EX», например, gsub("on", "EX") выдаст "CommEXCar::RedTrunk", а tr("on", "EX") выдаст "CEmmEXCar::RedTruXk".

Документы:

https://apidock.com/ruby/String/gsub

https://apidock.com/ruby/String/sub

https://apidock.com/ruby/String/tr

Это решение на чистом Ruby.

r = /(?<=[a-z])(?=[A-Z])|::/
"CommonCar::RedTrunk".gsub(r, '_').downcase
  #=> "common_car_red_trunk"

См. (первая форма) String#gsub и String#downcase.

Регулярное выражение можно сделать самодокументируемым, написав его в режиме свободного пробела:

r = /
    (?<=[a-z]) # assert that the previous character is lower-case
    (?=[A-Z])  # assert that the following character is upper-case
    |          # or
    ::         # match '::'
    /x         # free-spacing regex definition mode

(?<=[a-z]) — положительный взгляд назад; (?=[A-Z]) — позитивный прогноз.

Обратите внимание, что /(?<=[a-z])(?=[A-Z])/ соответствует пустой строке ("нулевой ширины"). r соответствует, например, пустой строке между 'Common' и 'Car', потому что ей предшествует строчная буква, а за ней следует прописная.

Я не знаю Rails, но думаю, вы могли бы написать

"CommonCar::RedTrunk".delete(':').underscore

Другие вопросы по теме