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
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
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

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