Перетворення футляра верблюда в корпус підкреслення в рубіні


232

Чи є якась готова функція, яка перетворює рядки верблюда у строках, виділених підкресленням?

Я хочу щось подібне:

"CamelCaseString".to_underscore      

щоб повернути "camel_case_string".

...


43
FYI: Малі та підкреслені "офіційно" називаються випадками змій
Ендрю

3
Дивно бачити "офіційно" у лапках, і все ж, це найкращий спосіб описати це.
stevenspiel

Чомусь я бачу відсутність методу змії. Рейки 4.
Абрам

Відповіді:


362

Rails 'ActiveSupport додає підкреслення до рядка за допомогою наступного:

class String
  def underscore
    self.gsub(/::/, '/').
    gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
    gsub(/([a-z\d])([A-Z])/,'\1_\2').
    tr("-", "_").
    downcase
  end
end

Тоді ви можете робити цікаві речі:

"CamelCase".underscore
=> "camel_case"

5
Якщо ви зміните tr("-","_")на tr("- ","_")(пробіл, доданий до першої параметри), це також перетворить пробіли в підкреслення. Крім того, я не думаю, що вам навіть не потрібно включати self.або принаймні це працює для мене під Ruby 1.9.3.
Gus Shortz

6
require 'active_support/core_ext/string'
konsolebox

Функція підкреслення Активне використання: github.com/rails/rails/blob/…
GreeKatrina

Підкреслення - це метод Rails not rubin , див. apidock.com/rails/String/underscore .
С.Ядав

1
@ S.Yadav true метод - це Rails, тому ви не можете викликати підкреслення за замовчуванням, але, надаючи використаний код і посилаючись на рейки як джерело, ця відповідь є корисною для рубіну. Він говорить, що ви можете включати рейки або просто включіть цю функцію, яку написала та протестувала команда рейок.
Майкл Горман

99

Можна використовувати

"CamelCasedName".tableize.singularize

Або просто

"CamelCasedName".underscore

Обидва варіанти способів дадуть результат "camel_cased_name". Ви можете ознайомитись з більш детальною інформацією тут .


11
Це є частиною реалізації ActiveSupport :: інфлектора, в без нього, ви не можете використовувати ці розширення String (спробуйте в чистому IRB консолі: «ThisCamelCaseString» .underscore, то потрібно «active_support / інфлектор» і спробуйте ще раз)
Євгенія Манолов

3
На етикетці ОП написано "рубін на рейках"
Жульєн Ламарш

55

Реалізація Ruby:

class String
   # ruby mutation methods have the expectation to return self if a mutation occurred, nil otherwise. (see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-gsub-21)
   def to_underscore!
     gsub!(/(.)([A-Z])/,'\1_\2')
     downcase!
   end

   def to_underscore
     dup.tap { |s| s.to_underscore! }
   end
end

Так "SomeCamelCase".to_underscore # =>"some_camel_case"


2
як інші рішення не є рубіном?
jrhicks

О, ш ... Спасибі - мені було більше цікаво писати, ніж читати. Як результат - посилання на Rails змусили мене вважати, що інші фрагменти є специфічними для Rails. Відповідь змінили ...
kirushik

1
в моїй редакції є ще одна помилка, і не видається, що я можу її виправити. Ось виправлений код: gist.github.com/4027440
Тім Харпер

6
Ви можете /([^A-Z])([A-Z]+)/замість цього подумати , щоб обробити "ALLCAPS"-> "allcaps"замість"a_ll_ca_ps"
Невір

4
Це насправді 10-лайнер!
Крістіанп

30

Існує вбудований метод Rails під назвою "підкреслення", який ви можете використовувати для цієї мети

"CamelCaseString".underscore #=> "camel_case_string" 

Метод "підкреслення", як правило, можна вважати зворотним до "камелі"


1
невизначений метод `підкреслити 'для" ... ": Рядок
Доріан

5
Це метод ActiveSupport
Доріан

20

Ось як це робить Rails :

   def underscore(camel_cased_word)
     camel_cased_word.to_s.gsub(/::/, '/').
       gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
       gsub(/([a-z\d])([A-Z])/,'\1_\2').
       tr("-", "_").
       downcase
   end

1
Краще мати операнд як аргумент методу, а не вторгнутись у основний клас String.
Пістос

1
Не погоджуйтеся - краще, щоб він працював на класі таким, яким він має бути, інакше вам доведеться вставити його в модуль і пам'ятати, щоб включити його там, де вам це потрібно.
Ghoti

1
Також цей метод все одно є частиною рядків Rails 3 :)
Ghoti

2
Якщо я можу перейти до цієї дискусії - краще, щоб вона вторглась у клас рядків, коли ви включите її =).
Еван Моран

7

Приймач, перетворений на випадок змії: http://rubydoc.info/gems/extlib/0.9.15/String#snake_case-instan_method

Це бібліотека підтримки для DataMapper та Merb. ( http://rubygems.org/gems/extlib )

def snake_case
  return downcase if match(/\A[A-Z]+\z/)
  gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
  gsub(/([a-z])([A-Z])/, '\1_\2').
  downcase
end

"FooBar".snake_case           #=> "foo_bar"
"HeadlineCNNNews".snake_case  #=> "headline_cnn_news"
"CNN".snake_case              #=> "cnn"

7

Ознайомтеся із змійкою з Ruby Facets

Розглядаються наступні випадки, як видно нижче:

"SnakeCase".snakecase         #=> "snake_case"
"Snake-Case".snakecase        #=> "snake_case"
"Snake Case".snakecase        #=> "snake_case"
"Snake  -  Case".snakecase    #=> "snake_case"

Від: https://github.com/rubyworks/facets/blob/master/lib/core/facets/string/snakecase.rb

class String

  # Underscore a string such that camelcase, dashes and spaces are
  # replaced by underscores. This is the reverse of {#camelcase},
  # albeit not an exact inverse.
  #
  #   "SnakeCase".snakecase         #=> "snake_case"
  #   "Snake-Case".snakecase        #=> "snake_case"
  #   "Snake Case".snakecase        #=> "snake_case"
  #   "Snake  -  Case".snakecase    #=> "snake_case"
  #
  # Note, this method no longer converts `::` to `/`, in that case
  # use the {#pathize} method instead.

  def snakecase
    #gsub(/::/, '/').
    gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
    gsub(/([a-z\d])([A-Z])/,'\1_\2').
    tr('-', '_').
    gsub(/\s/, '_').
    gsub(/__+/, '_').
    downcase
  end

  #
  alias_method :underscore, :snakecase

  # TODO: Add *separators to #snakecase, like camelcase.

end

Це не працює з рядком зі спеціальним символом. Приклад:"Dumb Penguin's Egg".snakecase # => "dumb_penguin's_egg"
khiav reoy

6

Короткий ліній для CamelCases, якщо у вас також пробіли (не працює правильно, якщо у вас є слово між маленькою початковою літерою):

a = "Test String"
a.gsub(' ', '').underscore

  => "test_string"

1
underscoreне входить до складу рубіну
dft

4

У випадку, якщо хтось шукає випадок, коли йому потрібно застосувати підкреслення до рядка з пробілами і хочете перетворити їх на підкреслення, ви можете використовувати щось подібне

'your String will be converted To underscore'.parameterize.underscore
#your_string_will_be_converted_to_underscore

Або просто використовуйте .parameterize ('_'), але майте на увазі, що ця застаріла

'your String will be converted To underscore'.parameterize('_')
#your_string_will_be_converted_to_underscore

1

Я хотів би цього:

class String

  # \n returns the capture group of "n" index
  def snikize
    self.gsub(/::/, '/')
    .gsub(/([a-z\d])([A-Z])/, "\1_\2")
    .downcase
  end

  # or

  def snikize
    self.gsub(/::/, '/')
    .gsub(/([a-z\d])([A-Z])/) do
      "#{$1}_#{$2}"
    end
    .downcase
  end

end

Мавпа патч Stringкласу. Є клас, який починається з двох або більше літер великими літерами.


Вам потрібно змінити , "\1_\2"щоб в '\1_\2'іншому випадку ви будете в кінцевому підсумку з "came\u0001_\u0002ase"замість , "camel_case"як Рубі 2.5 ... може бути , інші , а також.
6
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.